Copy add or combine a model - c#

I am having problem adding to the model. I want to have a list in the Root1 or in the Viewmodel like fullname and authors list.
newModel1
AuthorsAccepted count=4
FullName = Jack
AuthorsAccepted count=4
FullName = Time Dean
With the code below it only adds the last one to the Root1. I created a a third model. Is there a way I can add to the third model both the lists or in Root1.
var fullName = "Jack";
var fullName2 = "Tim Dean";
var authors1 = new List<AuthorsAccepted1>() {
new AuthorsAccepted1(){ id = 1, Name="Bill"},
new AuthorsAccepted1(){ id = 2, Name="Steve"},
new AuthorsAccepted1(){ id = 3, Name="jon"},
new AuthorsAccepted1(){ id = 4, Name="nick"}
};
var authors2 = new List<AuthorsAccepted1>() {
new AuthorsAccepted1(){ id = 1, Name="jack"},
new AuthorsAccepted1(){ id = 2, Name="tim"},
new AuthorsAccepted1(){ id = 3, Name="james"},
new AuthorsAccepted1(){ id = 4, Name="mary"}
};
var newModel1 = new Root1();
newModel1.FullName = fullName;
newModel1.AuthorsAccepted = authors1;
var newModel2 = new Root1();
newModel2.FullName = fullName2;
newModel2.AuthorsAccepted = authors2;
}
}
public class Root1
{
public string FullName { get; set; }
public List<AuthorsAccepted1> AuthorsAccepted { get; set; }
}
public class AuthorsAccepted1
{
public string Name { get; set; }
public int id { get; set; }
}
public class Viewmodel
{
public Root1 AllModel { get; set; }
}

Related

Remove from a list that has a list within it based on integer list

I have a list that basically look like this...
public class Area
{
public int Id { get; set; }
public string Name { get; set; }
public List<ZipCodeAdresses> ListOfIncludedDestinations { get; set; }
}
public class ZipCodeAdresses
{
public int AreaId { get; set; }
public List<Person> AdressList { get; set; }
}
public class Person
{
public string MottagarNamn { get; set; }
public string Street { get; set; }
}
var intListToRemove = new List<int>(){2,3};
var list = new List<Area>();
var subList = new List<ZipCodeAdresses>();
var personList = new List<Person>
{
new Person() {MottagarNamn = "User 1"},
new Person() {MottagarNamn = "User 2"}
};
subList.Add(new ZipCodeAdresses(){AdressList = personList , AreaId = 1});
personList = new List<Person>
{
new Person() {MottagarNamn = "User 3"},
new Person() {MottagarNamn = "User 4"}
};
subList.Add(new ZipCodeAdresses() { AdressList = personList, AreaId = 2 });
list.Add(new Area(){Name = "List A", ListOfIncludedDestinations = subList});
subList = new List<ZipCodeAdresses>();
personList = new List<Person>
{
new Person() {MottagarNamn = "User 5"},
new Person() {MottagarNamn = "User 6"}
};
subList.Add(new ZipCodeAdresses() { AdressList = personList, AreaId = 3 });
personList = new List<Person>
{
new Person() {MottagarNamn = "User 7"},
new Person() {MottagarNamn = "User 8"}
};
subList.Add(new ZipCodeAdresses() { AdressList = personList, AreaId = 4 });
list.Add(new Area() { Name = "List B", ListOfIncludedDestinations = subList });
I need to be able to remove from the list ListOfIncludedDestinations where AreaId is equal to any integer in intListToRemove which in this example is 2 and 3?
List<T> contains a method RemoveAll, that removes all entries that fulfill a certain condition. In your case it is:
foreach(var entry in list)
{
entry.ListOfIncludedDestinations.RemoveAll(x => intListToRemove.Contains(x.AreaId));
}
This loops through your list, and for every entry it removes all entries in ListOfIncludedDestinations that have an AreadId which is in intListToRemove.
Online demo: https://dotnetfiddle.net/ialnPb
You should add this sample code to remove them from the list :
foreach (var i in list)
i.ListOfIncludedDestinations.RemoveAll(o => intListToRemove.Contains(o.AreaId));

Query mongo document array

I have the next mongo document structure :
_id
-countryCode
-keywordID
-name
-displayName
-categories:[Array]
-_id
-name
-position
-canonical
I would like to get all the keywords that are in a specific category only knowing the category's ID. I am using the mongo C# driver but don't know how could I check what's inside that array.
I would like to send a list with the category ID's and get back all the keywords that have a category from that list.
public async Task<List<Keyword>> GetKeywords(List<long> keywordCatIds, string countryCode)
{
var mongoCollection = MongoDatabase.GetCollection<Keyword>("Keywords");
try
{
FilterDefinition<Keyword> mongoFilter = Builders<Keyword>.Filter.In(c=>c.Categories, keywordCatIds);
return await mongoCollection.Find(mongoFilter,null).ToListAsync<Keyword>();
}
catch (Exception ex)
{
Logger.Error(ex, "Multiple ids for Country Code: {0}, ids: {1}", countryCode, string.Join(',', keywordCatIds.Select(s => s)));
return null;
}
}
Your In function looks like a "categories._id" filter in normal mongoDB. Which transitions into an ElemMatch. I created a project which fills the db, than selects
all the keywords that are in a specific category only knowing the category's ID
public class CustomID
{
public string CountryCode { get; set; }
public long KeywordId { get; set; }
public string Name { get; set; }
}
public class Keyword
{
[BsonId]
public CustomID Id { get; set; }
public List<Category> Categories { get; set; }
}
public class Category
{
[BsonId]
public long Id { get; set; }
public string Name { get; set; }
public int Position { get; set; }
}
internal class Program
{
public static IMongoDatabase MongoDatabase { get; private set; }
public static async Task Main()
{
var conventionPack = new ConventionPack
{
new CamelCaseElementNameConvention()
};
ConventionRegistry.Register(
"CustomConventionPack",
conventionPack,
t => true);
var client = new MongoClient();
MongoDatabase = client.GetDatabase("SO");
var ret = await GetKeywords(new List<long> {1L, 2L}, "HU-hu");
// ret is A and B. C is filtered out because no category id of 1L or 2L, D is not HU-hu
}
public static async Task<List<Keyword>> GetKeywords(List<long> keywordCatIds, string countryCode)
{
var mongoCollection = MongoDatabase.GetCollection<Keyword>("keywords");
// be ware! removes all elements. For debug purposes uncomment>
//await mongoCollection.DeleteManyAsync(FilterDefinition<Keyword>.Empty);
await mongoCollection.InsertManyAsync(new[]
{
new Keyword
{
Categories = new List<Category>
{
new Category {Id = 1L, Name = "CatA", Position = 1},
new Category {Id = 3L, Name = "CatC", Position = 3}
},
Id = new CustomID
{
CountryCode = "HU-hu",
KeywordId = 1,
Name = "A"
}
},
new Keyword
{
Categories = new List<Category>
{
new Category {Id = 2L, Name = "CatB", Position = 2}
},
Id = new CustomID
{
CountryCode = "HU-hu",
KeywordId = 2,
Name = "B"
}
},
new Keyword
{
Categories = new List<Category>
{
new Category {Id = 3L, Name = "CatB", Position = 2}
},
Id = new CustomID
{
CountryCode = "HU-hu",
KeywordId = 3,
Name = "C"
}
},
new Keyword
{
Categories = new List<Category>
{
new Category {Id = 1L, Name = "CatA", Position = 1}
},
Id = new CustomID
{
CountryCode = "EN-en",
KeywordId = 1,
Name = "EN-A"
}
}
});
var keywordFilter = Builders<Keyword>.Filter;
var categoryFilter = Builders<Category>.Filter;
var mongoFilter =
keywordFilter.ElemMatch(k => k.Categories, categoryFilter.In(c => c.Id, keywordCatIds)) &
keywordFilter.Eq(k => k.Id.CountryCode, countryCode);
return await mongoCollection.Find(mongoFilter).ToListAsync();
}
}

How to populate array element defined inside the class

How to populate array element defined inside the class? I would like to Populate List of student with array of Marks,which i am not able to locate .
public class Marks
{
public int ENG { get; set; }
public int MATHS { get; set; }
}
public class Student
{
public string empName { set; get; }
public string empAddress { set; get; }
public Marks[] StudentMarks { set; get; }
}
var objs = new List<Student>()
{
new Employee() {empName = "Manish" empAddress = "MUM"....array element with Marks of two subjects
new Employee() {empName = "Manoj", empAddress = "MUM"....arrayelement with Marks of two subjects
}
In order to initialize array in a single line you should use one of the following code
int[] n1 = new int[4] {2, 4, 6, 8};
int[] n2 = new int[] {2, 4, 6, 8};
int[] n3 = {2, 4, 6, 8};
In your case, you should populate your array with Marks objects.
Marks[] MarksArray = new [] {new Marks() {ENG = 1, MATHS = 1}, new Marks() {ENG = 2, MATHS = 2}};
This array contains 2 marks - new Marks() {ENG = 1, MATHS = 1} and new Marks() {ENG = 2, MATHS = 2}.
You can read find more examples here - https://msdn.microsoft.com/en-us/library/aa287601(v=vs.71).aspx
So you can create your objects this way
var objs = new List<Student>()
{
new Student() {empName = "Manish", empAddress = "MUM", StudentMarks = new [] {new Marks() {ENG = 1, MATHS = 1}, new Marks() {ENG = 2, MATHS = 2}} },
new Student() {empName = "Manish", empAddress = "MUM", StudentMarks = new [] {new Marks() {ENG = 1, MATHS = 1}, new Marks() {ENG = 2, MATHS = 2}} },
};
If you were concerned with the syntax only then this would do:
void Main()
{
var objs = new List<Employee>()
{
new Employee() {
empName = "Manish",
empAddress = "MUM",
StudentMarks = new Marks[] {
new Marks {ENG=10, MATHS = 100},
new Marks { ENG=20, MATHS = 80}, }},
new Employee() {
empName = "Manoj",
empAddress = "MUM",
StudentMarks = new Marks[] {
new Marks { ENG=59, MATHS = 40},
new Marks { ENG=60, MATHS = 80},
new Marks { ENG=80, MATHS = 10},
new Marks { MATHS = 90},
new Marks { ENG=70},}
},
};
foreach (var student in objs)
{
Console.WriteLine("{0} - {1}", student.empName, student.empAddress);
foreach (var mark in student.StudentMarks)
{
Console.WriteLine("Eng:{0}, Maths:{1}", mark.ENG, mark.MATHS);
}
}
}
public class Marks
{
public int ENG { get; set; }
public int MATHS { get; set; }
}
public class Student
{
public string empName { set; get; }
public string empAddress { set; get; }
public Marks[] StudentMarks { set; get; }
}
public class Employee : Student
{ }
However, that is not a good model. A better model would be like this:
void Main()
{
var objs = new List<Student>()
{
new Student() {
Name = "Manish",
Address = "MUM",
StudentMarks = new List<Mark> {
new Mark {Name="Eng", Score = 50},
new Mark {Name="Maths", Score = 60},
}
},
new Student() {
Name = "Manoj",
Address = "MUM",
StudentMarks = new List<Mark> {
new Mark {Name="Maths", Score = 100},
new Mark {Name="Eng", Score = 80},
new Mark {Name="Eng", Score = 70},
new Mark {Name="Eng", Score = 90},
new Mark {Name="Maths", Score = 90},
}
},
};
foreach (var student in objs)
{
Console.WriteLine("{0} - {1}", student.Name, student.Address);
foreach (var mark in student.StudentMarks)
{
Console.WriteLine("Name:{0}, Score:{1}", mark.Name, mark.Score);
}
}
}
public class Mark
{
public string Name { get; set; }
public int Score { get; set; }
}
public class Student
{
public string Name { set; get; }
public string Address { set; get; }
public List<Mark> StudentMarks { set; get; }
}
This one is still not very good. A better one might be:
void Main()
{
var objs = new List<Student>()
{
new Student() {
Name = "Manish",
Address = "MUM",
StudentMarks = new Dictionary<string,List<int>> {
{"Maths", new List<int> {60,70,50}},
{"Eng", new List<int> {80,70,90}},
}
},
new Student() {
Name = "Manoj",
Address = "MUM",
StudentMarks = new Dictionary<string,List<int>> {
{"Maths", new List<int> {70,90}},
{"Eng", new List<int> {40,50,60,60}},
}
},
};
foreach (var student in objs)
{
Console.WriteLine("{0} - {1}", student.Name, student.Address);
foreach (var course in student.StudentMarks)
{
Console.WriteLine("Course:{0}, Average:{1}", course.Key, course.Value.Average());
foreach (var score in course.Value)
{
Console.WriteLine(score);
}
}
}
}
public class Mark
{
public string Name { get; set; }
public int Score { get; set; }
}
public class Student
{
public string Name { set; get; }
public string Address { set; get; }
public Dictionary<string,List<int>> StudentMarks { set; get; }
}
And there are better ones.

Linq : Comparing 1 Child Collection to (Aggregated) ChildCollection(s)

I have a Linq question: (DotNet Framework 4.0)
I have the following classes:
public class Employee
{
public Guid? EmployeeUUID { get; set; }
public string SSN { get; set; }
}
public class JobTitle
{
public Guid? JobTitleSurrogateKey { get; set; }
public string JobTitleName { get; set; }
}
public class EmployeeToJobTitleMatchLink
{
public EmployeeToJobTitleMatchLink()
{
this.TheJobTitle = new JobTitle() { JobTitleSurrogateKey = Guid.NewGuid(), JobTitleName = "SomeJobTitle:" + Guid.NewGuid().ToString("N") };
}
public Guid LinkSurrogateKey { get; set; }
/* Related Objects */
public Employee TheEmployee { get; set; }
public JobTitle TheJobTitle { get; set; }
}
public class Organization
{
public Organization()
{
this.Links = new List<EmployeeToJobTitleMatchLink>();
}
public int OrganizationSurrogateKey { get; set; }
public ICollection<EmployeeToJobTitleMatchLink> Links { get; set; }
}
In my code below, I can compare 2 child-collections and get the results I need (in "matches1".
Here I am using the "SSN" string property to compare and find the overlaps. And the Console.Write for matches1 works as I expect.
What I don't know how to do is compare the first child collection (org10) to all the children in (allOtherOrgsExceptOrg10 (all the Organizations and all the Links of these Organizations )
The commented out code shows kinda what I'm trying to do, one of my many feeble attempts today.
But basically, match2 would be populated with all the SSN overlaps...but comparing org10 with allOtherOrgsExceptOrg10, all their "Links", and their Employee.SSN's.
org10 overlaps with org20 with "AAA", so match2 would contain "AAA". and org10 overlaps with org30 with "BBB" so match2 would contain "BBB".
Organization org10 = new Organization();
org10.OrganizationSurrogateKey = 10;
Employee e11 = new Employee() { SSN = "AAA", EmployeeUUID = new Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA") };
EmployeeToJobTitleMatchLink link11 = new EmployeeToJobTitleMatchLink();
link11.TheEmployee = e11;
org10.Links.Add(link11);
Employee e12 = new Employee() { SSN = "BBB", EmployeeUUID = new Guid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB") };
EmployeeToJobTitleMatchLink link12 = new EmployeeToJobTitleMatchLink();
link12.TheEmployee = e12;
org10.Links.Add(link12);
Organization org20 = new Organization();
org20.OrganizationSurrogateKey = 20;
Employee e21 = new Employee() { SSN = "AAA", EmployeeUUID = new Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA") };
EmployeeToJobTitleMatchLink link21 = new EmployeeToJobTitleMatchLink();
link21.TheEmployee = e21;
org20.Links.Add(link21);
Employee e22 = new Employee() { SSN = "CCC", EmployeeUUID = new Guid("CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC") };
EmployeeToJobTitleMatchLink link22 = new EmployeeToJobTitleMatchLink();
link22.TheEmployee = e22;
org20.Links.Add(link22);
Organization org30 = new Organization();
org30.OrganizationSurrogateKey = 30;
Employee e31 = new Employee() { SSN = "BBB", EmployeeUUID = new Guid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB") };
EmployeeToJobTitleMatchLink link31 = new EmployeeToJobTitleMatchLink();
link31.TheEmployee = e31;
org30.Links.Add(link31);
Employee e32 = new Employee();
e32.SSN = "ZZZ";
EmployeeToJobTitleMatchLink link32 = new EmployeeToJobTitleMatchLink();
link32.TheEmployee = e32;
org30.Links.Add(link32);
IList<Organization> allOtherOrgsExceptOrg10 = new List<Organization>();
/* Note, I did not add org10 here */
allOtherOrgsExceptOrg10.Add(org20);
allOtherOrgsExceptOrg10.Add(org30);
IEnumerable<EmployeeToJobTitleMatchLink> matches1 =
org10.Links.Where(org10Link => org20.Links.Any(org20Link => org20Link.TheEmployee.SSN.Equals(org10Link.TheEmployee.SSN, StringComparison.OrdinalIgnoreCase)));
IEnumerable<EmployeeToJobTitleMatchLink> matches2 = null;
//org10.Links.Where(org10Link => ( allOtherOrgs.Where ( anyOtherOrg => anyOtherOrg.Links.Any(dbSideChild => dbSideChild.TheEmployee.SSN == org10Link.TheEmployee.SSN)) );
if (null != matches1)
{
foreach (EmployeeToJobTitleMatchLink link in matches1)
{
Console.WriteLine(string.Format("matches1, SSN = {0}", link.TheEmployee.SSN));
}
}
if (null != matches2)
{
foreach (EmployeeToJobTitleMatchLink link in matches2)
{
Console.WriteLine(string.Format("matches2, SSN = {0}", link.TheEmployee.SSN));
}
}
matches2 =
allOtherOrgsExceptOrg10.SelectMany(x => x.Links)
.Where(x => org10.Links.Select(o => o.TheEmployee.SSN).Contains(x.TheEmployee.SSN));
You can use the SelectMany on the allOther collection to select all Links over all org's. Then check if any SSN is inside the org10 List.
See: http://msdn.microsoft.com/en-us/library/system.linq.enumerable.selectmany(v=vs.100).aspx
You can use SelectMany to flatten out the collection and then use it just like you have for matches1
IEnumerable<EmployeeToJobTitleMatchLink> matches2 =
org10.Links.Where(
org10Link =>
allOtherOrgsExceptOrg10.SelectMany(allOtherOrgs => allOtherOrgs.Links).Any(
anyOtherLink =>
anyOtherLink.TheEmployee.SSN.Equals(org10Link.TheEmployee.SSN, StringComparison.OrdinalIgnoreCase)));
The SelectMany will make it seem like one IEnumerable instead of and IEnumerable of an IEnumerable.

Seeding Many to Many EF Code First Relationship

There are a few other posts on this topic that I saw but I was not able to get a correct answer yet (my own fault I am sure) but I want to seed a database and I have set up a many to many relationship, but I can't figure out how to seed the second entity with the first entities id.
var users = new List<User>()
{
new User()
{
Id = 1,
FirstName = "Clark",
LastName = "Kent"
},
new User()
{
Id = 2,
FirstName = "Lex",
LastName = "Luther"
}
};
users.ForEach(p => context.Users.Add(p));
var messages = new List<Message>()
{
new Message()
{
Id = 1,
SenderId = 2,
Recipients = new List<User> { Id = 2, Id = 3} // <<< Problem is here
}
}
messages.ForEach(p => context.Messages.Add(p));
base.Seed(context);
My message class.
public class Message
{
public int Id { get; set; }
public int SenderId { get; set; }
public int RecipientsId { get; set; }
public virtual User Sender { get; set; }
public virtual ICollection<User> Recipients { get; set; }
}
My user class.
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Message> Messages { get; set; }
}
To be clear - I can properly seed users with no problem, if there are any typos or copy paste errors they aren't a big deal because I know everything is working besides being able to create a list of recipients that have already been seeded.
Thanks in advance
This is an old thread but Ive just had a similar problem so thought I would offer an answer.
You need to query your users object created above
var messages = new List<Message>()
{
new Message()
{
Id = 1,
SenderId = 2,
Recipients = new List<User>()
{
users.Single(u => u.Id == 1),
users.Single(u => u.Id == 2)
}
}
First thing i notice is that you are adding Ints to the recipients list, not user objects
What happens if you try code like this:
var users = new List<User>()
{
new User()
{
Id = 1,
FirstName = "Clark",
LastName = "Kent"
},
new User()
{
Id = 2,
FirstName = "Lex",
LastName = "Luther"
}
};
users.ForEach(p => context.Users.Add(p));
var messages = new List<Message>()
{
new Message()
{
Id = 1,
SenderId = 2,
Recipients = new List<User> {users[0],users[1] } // <<< Problem is here
}
}
messages.ForEach(p => context.Messages.Add(p));
context.SaveChanges();
or you could event try this:
var users = new List<User>()
{
new User()
{
Id = 1,
FirstName = "Clark",
LastName = "Kent"
},
new User()
{
Id = 2,
FirstName = "Lex",
LastName = "Luther"
}
};
users.ForEach(p => context.Users.Add(p));
var messages = new List<Message>()
{
new Message()
{
Id = 1,
SenderId = 2,
Recipients = new List<User> {context.Users.Where(u=>u.Id==1),context.Users.Where(u=>u.Id==1) }
}
}
messages.ForEach(p => context.Messages.Add(p));
context.SaveChanges();

Categories

Resources