c# Nested Dictionary, better alternative? best organize data across three classes - c#

Suppose
There is a Trend class.
public class Trend{
public string TrendName { get; set; }
public string Description { get; set; }
}
e.g.
new Trend() { TrendName= "Pizza", Description="yum yum" };
new Trend() { TrendName= "Clothing", Description="ba yum" };
new Trend() { TrendName= "Food" };
There is a Person class.
public class Person {
public string PersonName { get; }
public int PersonId { get; }
public int aptitude { get; }
...... many other properties
}
e.g.
new Person() { PersonName = "Arnold Palmer" };
new Person() { PersonName = "Ken Hemingway" };
There is a thing class.
public class TrendyItem
{
public string ItemName { get; }
public string ItemId { get; }
}
e.g.
new TrendyItem() { ItemName = "PotatoPizza" }
new TrendyItem() { ItemName = "PeplumSkirt" }
There is a TrendysOfYear class. This class already has.
public class TrendProfile
{
public List<Trend> FavoriteTrendsOfYear;
public List<Person> ActivePeopleThisYear;
public List<TrendyItem> TrendyItemsThisYear;
}
For every TrendysOfYear,
There will be a list of different trends, FavoriteTrendsOfYear,
each person belonging to the ActivePeopleThisYear
will specifiy a "TrendyItem"
Given a TrendProfile, I want to be able to be able to quickly look up
1) Input: Person; Output: List of Person's choice on trendy items.
2) Input: Trend; Output: List of trendy items belonging to that trend.
I've considered two ways.
A) Dictionary<Person, Dictionary<Trend, TrendyItem>>
You can get PersonsChoiceOnTrendyItem = dic[Person].Values.ToList();
but have to loop through and build new list everytime you look up TrendyItemsOfTrend.
B) Dictionary<Trend, Dictionary<Person, TrendyItem>>
vice cesra.
Is it a good practice to use these custom objects for dictionary keys?
Is it a good practice to use nested dictionaries?
What's the best way to map items in this case?
Also, not that Trend class does not have integer Id, so will have to used the string (the name of the trend is guaranteed to be unique) as key.
Additional Info: properties of Trend such as TrendName and Description are editable. So i'm a little hesitant to add collection of TrendyItems to Trend class. If there is Trend, "Fashionn" in TrendProfile1 and TrendProfile2, and someone decides to change the name to "Fashion", I want both profiles to reference the same object.

Typically you don't see the objects that contain values used as keys in this way. Usually you will identify some unique key on your object and use that as key and the object itself as the value. For example you could store Person objects in a Dictionary where the person's name is the key, and Person is the value.
Instead of nested Dictionaries, you should consider adding Collections to your objects. For example, you could add a List<TrendyItem> to Trend to maintain that relationship.
Here is an alternative way that you could organize the classes. I'm not exactly sure what the scope is of each of your collections, but this should give you another way to look at the problem.
public class Trend
{
public string TrendName { get; set; }
public string Description { get; set; }
// This maintains the relationship between Trend and TrendyItem
public List<TrendyItem> Items { get; set; }
}
public class Person
{
public string PersonName { get; set; }
public int PersonId { get; set; }
public int aptitude { get; set; }
// Each person will specifiy a "TrendyItem"
public TrendyItem Choice { get; set; }
}
public class TrendyItem
{
public string ItemName { get; set; }
public string ItemId { get; set; }
}
public class TrendProfile
{
// Change this to to a key value pair. The key will be how you uniquely identify (input) the Trend in
//2) Input: Trend; Output: List of trendy items belonging to that trend.
// For example TrendName
public Dictionary<string, Trend> FavoriteTrendsOfYear;
// Change this to to a key value pair. The key will be how you uniquely identify (input) the Person in
// 1) Input: Person; Output: List of Person's choice on trendy items.
// For example PersonName
public Dictionary<string, Person> ActivePeopleThisYear;
public List<TrendyItem> TrendyItemsThisYear;
}
With that class structure, you can easily answer the questions in your post.
static void Main()
{
TrendProfile trendProfile = new TrendProfile();
trendProfile.FavoriteTrendsOfYear = new Dictionary<string, Trend> {
{ "Pizza", new Trend() {
TrendName = "Pizza",
Description = "yum yum",
Items = new List<TrendyItem> {
new TrendyItem() {ItemName = "PotatoPizza1"},
new TrendyItem() {ItemName = "PotatoPizza2"},
new TrendyItem() {ItemName = "PotatoPizza3"}
}
}},
{ "Clothing", new Trend() {
TrendName = "Clothing",
Description = "ba yum",
Items = new List<TrendyItem> {
new TrendyItem() {ItemName = "PeplumSkirt1"},
new TrendyItem() {ItemName = "PeplumSkirt2"},
new TrendyItem() {ItemName = "PeplumSkirt3"}
}
}}
};
trendProfile.ActivePeopleThisYear = new Dictionary<string, Person> {
{ "Arnold Palmer", new Person() { PersonName = "Arnold Palmer", Choice = trendProfile.FavoriteTrendsOfYear["Pizza"].Items[1] }},
{ "Ken Hemingway", new Person() { PersonName = "Ken Hemingway", Choice = trendProfile.FavoriteTrendsOfYear["Clothing"].Items[2] }},
};
//1) Input: Person; Output: List of Person's choice on trendy items.
string person = "Arnold Palmer";
Console.WriteLine(trendProfile.ActivePeopleThisYear[person].Choice.ItemName);
//2) Input: Trend; Output: List of trendy items belonging to that trend.
string trend = "Clothing";
foreach(TrendyItem item in trendProfile.FavoriteTrendsOfYear[trend].Items)
Console.WriteLine(item.ItemName);
}
UPDATE
To share Trends across TrendProfiles, you could first create a "master" List or Dictionary of Trends. Then when building each of the TrendProfliles, you could pick the Trends out of the "master".
// "Master" list of trends
List<Trend> trends = new List<Trend> {
new Trend() {
TrendName = "Pizza",
Description = "yum yum",
Items = new List<TrendyItem> {
new TrendyItem() {ItemName = "PotatoPizza1"},
new TrendyItem() {ItemName = "PotatoPizza2"},
new TrendyItem() {ItemName = "PotatoPizza3"}
}
},
new Trend() {
TrendName = "Clothing",
Description = "ba yum",
Items = new List<TrendyItem> {
new TrendyItem() {ItemName = "PeplumSkirt1"},
new TrendyItem() {ItemName = "PeplumSkirt2"},
new TrendyItem() {ItemName = "PeplumSkirt3"}
}
}
};
TrendProfile trendProfile1 = new TrendProfile();
trendProfile1.FavoriteTrendsOfYear = new Dictionary<string, Trend> {
{ trends[0].TrendName, trends[0] },
{ trends[1].TrendName, trends[1] }
};
TrendProfile trendProfile2 = new TrendProfile();
trendProfile2.FavoriteTrendsOfYear = new Dictionary<string, Trend> {
{ trends[1].TrendName, trends[1] }
};

Related

DataGridView not displaying properties containing Lists

I have an object like so
public class Person{
public int ID { get; set; }
public string Name{ get; set; }
public string Surname{ get; set; }
public List<int> AltIDs { get; set; }
public List<string> AltNames{ get; set; }
}
I am setting data into the DataGridView like
dataGridView1.DataSource = null;
dataGridView1.DataSource = persons; // persons is List<Person>
However I only see 3 columns in the DataGridView that is of ID, Name and Surname, the properties with List<int> and List<string> seem to be ignored.
Is there a way to get theses properties showing up in the DataGridView? Probably like comma seperated values.
most probably the persons is null
you just change your code like this code
first Solution :
your model :
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public List<int> AltIDs { get; set; }
public List<string> AltNames { get; set; }
}
PersonViewModel :
public class PersonViewModel
{
public int ID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public int AltID { get; set; }
public string AltName { get; set; }
}
formLoad :
private void Form1_Load(object sender, EventArgs e)
{
List<Person> people = new List<Person>()
{new Person(){ ID=1,Name="a",Surname="a",AltIDs=new List<int>(){1,2,3,4 },AltNames=new List<string>(){"a","b","c" } },
new Person(){ ID=2,Name="b",Surname="b",AltIDs=new List<int>(){10,20,30,40 },AltNames=new List<string>(){"a","b","c" }},
new Person(){ ID=3,Name="c",Surname="c",AltIDs=new List<int>(){100,200,300,400 },AltNames=new List<string>(){"a","b","c" }},
new Person(){ ID=4,Name="d",Surname="d",AltIDs=new List<int>(){1000,2000,3000,4000 },AltNames=new List<string>(){"a","b","c" }},
new Person(){ ID=3,Name="e",Surname="e",AltIDs=new List<int>(){10000,20000,30000,40000 },AltNames=new List<string>(){"a","b","c" }}
};
List<PersonViewModel> pwm = new List<PersonViewModel>();
foreach (var person in people)
{
foreach(var id in person.AltIDs)
{
foreach (var name in person.AltNames)
pwm.Add(new PersonViewModel() { ID = person.ID, Name = person.Name, Surname = person.Surname, AltID = id, AltName = name });
}
}
dgv.DataSource = pwm;
}
Result :
Second Solution :
your model :
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public List<int> AltIDs { get; set; }
public List<string> AltNames { get; set; }
}
PersonViewModel :
public class PersonViewModel
{
public int ID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string AltID { get; set; }
public string AltName { get; set; }
}
FormLoad :
private void Form1_Load(object sender, EventArgs e)
{
List<Person> people = new List<Person>()
{new Person(){ ID=1,Name="a",Surname="a",AltIDs=new List<int>(){1,2,3,4 },AltNames=new List<string>(){"a","b","c" } },
new Person(){ ID=2,Name="b",Surname="b",AltIDs=new List<int>(){10,20,30,40 },AltNames=new List<string>(){"a","b","c" }},
new Person(){ ID=3,Name="c",Surname="c",AltIDs=new List<int>(){100,200,300,400 },AltNames=new List<string>(){"a","b","c" }},
new Person(){ ID=4,Name="d",Surname="d",AltIDs=new List<int>(){1000,2000,3000,4000 },AltNames=new List<string>(){"a","b","c" }},
new Person(){ ID=3,Name="e",Surname="e",AltIDs=new List<int>(){10000,20000,30000,40000 },AltNames=new List<string>(){"a","b","c" }}
};
List<PersonViewModel> pwm = new List<PersonViewModel>();
StringBuilder sbIds;
StringBuilder sbNames;
foreach (var person in people)
{
sbIds = new StringBuilder();
sbNames = new StringBuilder();
person.AltIDs.ForEach(c=> sbIds.Append(c.ToString()).Append(","));
person.AltNames.ForEach(c=> sbNames.Append(c).Append(","));
pwm.Add(new PersonViewModel() { ID = person.ID, Name = person.Name, Surname = person.Surname, AltID = sbIds.ToString().TrimEnd(','), AltName = sbNames.ToString().TrimEnd(',') });
}
dgv.DataSource = pwm;
}
Result :
When DataGridView is bound to DataSource, it auto generates columns for it for the properties with primitive datatypes such as int, string, double etc.
For the datatypes which are collections, DataGridViewComboBoxColumn is used. This type of column is not autogenerated. You need to add such columns manually in the GridView columns collection.
For your use case following is the solution.
Add DataGridView to the form and add columns to it manually from the Form's designer view by click on Add Column. You will have to add 3 DataGridViewTextBoxColumn and 2 DataGridViewComboBoxColumn.
After adding columns, the columns would look as following.
Now while assigning DataSource to the DataGridView you need to write following code. Here IdColumn, NameColumn, and SurnameColumn are the names give to columns when they were created in above steps.
dataGridView1.AutoGenerateColumns = false;
IdColumn.DataPropertyName = "ID";
NameColumn.DataPropertyName = "Name";
SurnameColumn.DataPropertyName = "Surname";
dataGridView1.DataSource = persons;
With the above code you will see Id, Name and Surname columns populated for persons in the collection but the dropdown lists in last two columns are empty.
To populate the dropdown list columns you need to add event handler for CellClick event of the DataGridView. And write following code there.
Here AltIdsColumn and AltNamesColumn are the names given to column when they created manually in earlier steps.
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
var altIdIndex = dataGridView1.Columns["AltIdsColumn"].Index;
var altNameIndex = dataGridView1.Columns["AltNamesColumn"].Index;
if (altIdIndex == e.ColumnIndex || altNameIndex == e.ColumnIndex)
{
var altIdsCell = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[altIdIndex];
var altNamesCell = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[altNameIndex];
if (altIdsCell.DataSource == null || altNamesCell.DataSource == null)
{
var person = dataGridView1.Rows[e.RowIndex].DataBoundItem as Person;
if (person != null)
{
altIdsCell.DataSource = person.AltIDs;
altNamesCell.DataSource = person.AltNames;
}
}
}
}
With this code, the dropdown list of AldIDs and AltNames columns will be populated when you click on those dropdown lists on individual rows.
I hope this will help you resolve your issue.
From what I can tell, this appears as a fairly basic “Master/Slave” type UI. In the grid, there is a “Person” object with the ID, Name and Surname. Obviously from your question, the AltIDs and AltNames Lists are NOT displayed in the grid.
This is due to the fact that the grid has a problem trying to add a “list of multiple” values into a “single” cell. As suggested, it is possible for you to “combine” the values into a “single” string and use that. However, this is extra work on your part and may create more work if the cell is edited.
One issue in this example is that, the AltIDs list for each Person could and will have a different number of elements. One possible solution is to simply ADD theses as new rows where the Person info (ID, Name and Surname) are duplicated. This will work but IMHO not very user friendly. The combo box option will also work, however again it may be confusing to users since a combo box “usually” indicates that the users selects a “single” value from many.
It is also possible to “flatten” each person object and have a column for each AltID in the list. This will work but the possibility of large gaps in the grid are likely. Again, not very user friendly. This is all doubled by the fact that there is another list AltNames that we have to take into account.
Given this, it appears clear that YOU are going to have to do extra work UNLESS you use an advanced third-party grid OR add more grids to the picture… in this case three (3) total. One for the person, another for the IDs and a third for the Names. Proper arrangement of the grids may be a little work, however, with three grids, it will make all the issues described above… go away. In addition the coding will be much easier.
It would be such that the user “selects” a Person from the first grid, then the second grid list all the AltID values and the third grid lists all the AltName values. If the “same” data source is used for each grid then… when the user selects a different Person in the person grid, the AltID grid and AltName grid will “automatically” update/refresh with the proper values. This will also make CRUD operations on any grid/value much easier.
The only problem I seen in the current Person class is that the two Lists are of “primitive” types. Used this way, the lists won’t display properly, the grid wants a CLASS. Therefore, you need to make a wrapper class for the AltID and AltName lists. Then change the list values in the Person class. Something like…
public class AltID_C {
public int AltID { get; set; }
}
public class AltName_C {
public string AltName { get; set; }
}
public class Person {
public int ID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public List<AltID_C> AltIDs { get; set; }
public List<AltName_C> AltNames { get; set; }
}
With this, all that is needed is to set each grid to the “same” data source, then set the AltID grids DataMember to the “AltIDs” property and set the AltNames grids DataMember to the “AltNames` property. Something like…
List<Person> AllPersons;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
AllPersons = GetRandomData(25);
dgvPerson.DataSource = AllPersons;
dgvAltID.DataSource = AllPersons;
dgvAltID.DataMember = "AltIDs";
dgvAltNames.DataSource = AllPersons;
dgvAltNames.DataMember = "AltNames";
}
Additional code below to complete the example.
private List<Person> GetRandomData(int numberOfPersons) {
List<Person> listOPeople = new List<Person>();
Person curPerson;
Random rand = new Random();
for (int i = 0; i < numberOfPersons - 1; i++) {
curPerson = new Person() {
ID = rand.Next(1, 1000),
Name = "Name_" + i + 1,
Surname = "Sname_" + i + 1,
AltIDs = GetRandomNumberOfInts(rand),
AltNames = GetRandomNumberOfStrings(rand)
};
listOPeople.Add(curPerson);
}
return listOPeople;
}
private List<AltID_C> GetRandomNumberOfInts(Random rand) {
List<AltID_C> listOInts = new List<AltID_C>();
int numberOfInts = rand.Next(0, 10);
for (int i = 0; i < numberOfInts - 1; i++) {
listOInts.Add(new AltID_C { AltID = rand.Next(1, 10000) });
}
return listOInts;
}
private List<AltName_C> GetRandomNumberOfStrings(Random rand) {
List<AltName_C> listOStrings = new List<AltName_C>();
int numberOfStrings = rand.Next(0, 10);
for (int i = 0; i < numberOfStrings - 1; i++) {
listOStrings.Add(new AltName_C { AltName = "RandString: " + rand.Next(1, 1000) });
}
return listOStrings;
}
Hope that helps.

Add values to Dictionary<int,class> not all at once

I'm trying to store data in a dictionary where the key is an ID and the values are of a class type. The class properties are not all added at the same time so I haven't used a constructor - unless there is a way to add new values using a constructor at a different times? The code below compiles, but I get a run time error saying the key has already been added.Thanks for the help.
public class Students
{
public string FirstName { get; set; }
public string SurName { get; set; }
public int Age { get; set; }
public double Score { get; set; }
}
public void cmdTEST_Click(object sender, EventArgs e)
{
Dictionary<int, Students> Data = new Dictionary<int, Students>();
Data.Add(5, new Students { FirstName = "Bob" });
Data.Add(5, new Students { Age = 34 }); // run time error - "key already added"
Data.Add(5, new Students { Score = 62 });
// extract data
double Score5 = Data[5].Score;
double Age5 = Data[5].Age;
}
You are adding same key multiple times which is not allowed. You can add all properties at once like below
Dictionary<int, Students> Data = new Dictionary<int, Students>();
Data.Add(5, new Students { FirstName = "Bob", Age = 34, Score = 62 });
And if you want to add values later you can use key to add values
Data.Add(5, new Students { FirstName = "Bob"});
Data[5].Age = 34;
Data[5].Score = 62;

how can I add a value to the list from the Dictionary<int,Object> and the list is in the Object

Ok.. I've seen some similar discussions so I hope this is unique enough.
I would like to initialize and modify data in a List
The list is a Property of the class User, which is inside a Dictionary
http://ideone.com/0YtpnC
internal class User
{
public string ID { get; set; }
public string Name { get; set; }
public List<ContactNumber> AddressBook { get; set; }
}
internal class Program
{
private static void Main(string[] args)
{
Dictionary<int, User> dic = new Dictionary<int, User>();
dic.Add(1, new User { ID = "id1", Name = "name1" });
dic.Add(2, new User { ID = "id2", Name = "name2" });
dic.Add(3, new User { ID = "id3", Name = "name3", AddressBook = new List<ContactNumber>(){new ContactNumber(3432),new ContactNumber(3213)} });
User user = dic.Where(z => z.Value.ID == "id3").FirstOrDefault().Value;
Console.WriteLine(user.Name);
DisplayList(user);
//Console.WriteLine(user.AddressBook.ToString());
//update the list
addOrUpdate(dic,3,user);
//var used = new User { ID = "id1", Name = "Harry" };
//dic[1] = used;
user = dic.Where(z => z.Value.ID == "id3").FirstOrDefault().Value;
Console.WriteLine(user.Name);
DisplayList(user);
}
private static void DisplayList(User user)
{
foreach (ContactNumber number in user.AddressBook)
{
Console.WriteLine(number.PhoneNumber);
}
}
//determin list length
public static void addOrUpdate(Dictionary<int, User> dic, int key, User user)
{
//sets a new user data and just replaces it in the dictionary
//var used = new User { ID = "id1", Name = "Harry" };
var used = new User{ ID = "id3", Name = "Henry" ,AddressBook = new List<ContactNumber>(){new ContactNumber(3111),new ContactNumber(4444)}};
if (dic.TryGetValue(key, out user))
{
// yay, value exists!
dic[key] = used;
}
else
{
// darn, lets add the value
dic.Add(key, used);
}
}
}
the problem is I want to get the user info and just add a contact number to the list. Currently it rewrites the entire list since I make a new version of list in the update function.
http://ideone.com/iI2Rxb
Simply:
dic[key].AddressBook.Add(new ContactNumber(666));
This seems to be a solution.
user.AddressBook.Add(new ContactNumber() { PhoneNumber = 121212});
from MSDN Docs
Wont below help, just add to the list (since it is referenced, it will update whatever you have been getting from the dictionary)
user.AddressBook.Add(...new contact number);

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.

Storing Class Data In A List

Well I have a class like this and I want to store in a list which is defined as a static variable. I was following the reference here: Storing data into list with class
public class Faculty
{
public string Name { get; set; }
public string Dept { get; set; }
public string[] subInterest = new string[4];
}
However when I try to initialize the list as follows I have problem with the array part: Invalid initializer member declarator
SaveDirectory.list_of_faculty.Add(
new Faculty
{
Name = txtTeachherName.Text,
Dept = cmbDepts.Items.CurrentItem.ToString(),
subInterest[0] = "HELLO"
});
What am I doing wrong?
You can't reach in to your object and initialize members of an array that it holds using initializer syntax. You could work around this as follows:
var fac = new Faculty {
Name = txtTeachherName.Text,
Dept = cmbDepts.Items.CurrentItem.ToString(),
subInterest = new []{"HELLO", null, null, null}}
or after initialization:
fac.subInterest[0] = "HELLO";
The problem is due to:
subInterest[0] = "HELLO"
You can not partially initialize an array in Object Initializer, either it is full or nothing, You can do:
subInterest = new string[]{"HELLO"}
But, this will leave the array subInterest with size 1, not as size 4, as you have defined in your class. To get the array of same size you can do:
subInterest = new string[]{"HELLO",null,null,null}
Another option is to use List<string> instead of an Array. You can initialize it with value and later you can add items to it.
Modify your class like:
public class Faculty
{
public string Name { get; set; }
public string Dept { get; set; }
public List<string> subInterest;
}
and then:
new Faculty
{
Name = txtTeachherName.Text,
Dept = cmbDepts.Items.CurrentItem.ToString(),
subInterest = new List<string>(){"HELLO"}
};
Using a constructor can also solve the problem like
public class Faculty
{
public string Name { get; set; }
public string Dept { get; set; }
public string[] subInterest = new string[4];
public Faculty(string name, string dept, string[] si)
{
this.Name = name;
this.Dept = dept;
this.subInterest = si;
}
}
Then instantiate the faculty class
string[] subinterest = new string[]{"reading","swmming",null,null};
var fac = new Faculty("dgdfgdfgfg","dfgdgfgdfg", subinterest);

Categories

Resources