compare two list of objects using linq dynamically - c#

Click to see the Output:
I have an Employee class
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public string Age { get; set; }
public string Address { get; set; }
public string ContactNo { get; set; }
}
and have fill method to fill lists
private static void FillEmployeeList(ref List<Employee> lt1, ref List<Employee> lt2)
{
lt1 = new List<Employee> {new Employee{ID=1,Name="Kavya",Age="24",Address="No.1,Nehru Street,Chennai",ContactNo="9874521456"},
new Employee{ID=2,Name="Ravi",Age="24",Address="Flat No.25/A1,Gandhi Street,Chennai",ContactNo="9658745258"},
new Employee{ID=3,Name="Lavnya",Age="30",Address="No.12,Shastri nagar,Chennai",ContactNo="5214587896"},
new Employee{ID=4,Name="Rupa",Age="31",Address="No.23/5,Nehru Street,Chennai",ContactNo="9874521256"},
new Employee{ID=5,Name="Divya",Age="32",Address="No.1/227,Nehru Street,Chennai",ContactNo="8541256387"},
};
lt2 = new List<Employee> {new Employee{ID=1,Name="Kavya",Age="24",Address="No.1,Nehru Street,Chennai",ContactNo="9874521456"},
new Employee{ID=2,Name="Ravindran",Age="30",Address="Flat No.25/A1,Gandhi Street,Chennai",ContactNo="9658745258"},
new Employee{ID=3,Name="Chandru",Age="30",Address="No.12,Shastri nagar,Chennai",ContactNo="5214587896"},
new Employee{ID=4,Name="Rakesh",Age="32",Address="No.23/5,Nehru Street,Chennai",ContactNo="9874021256"},
new Employee{ID=5,Name="Suresh",Age="32",Address="No.1/227,Nehru Street,Chennai",ContactNo="8541056387"},
new Employee{ID=11,Name="Suryakala",Age="28",Address="No.1,Pillayar koil Street,Chennai",ContactNo="9541204782"},
new Employee{ID=12,Name="Thivya",Age="41",Address="No.42,Ellaiamman koil Street,Chennai",ContactNo="9632140874"},
};
}
Comparing two list of objects
protected List<Employee> ListCompare(List<Employee> lt1, List<Employee> lt2)
{
FillEmployeeList(ref lt1, ref lt2);
List<Employee> lst = new List<Employee>();
if (lt1.Count > 0 && lt2.Count > 0)
{
// Displaying Matching Records from List1 and List2 by ID
var result = (from l1 in lt1
join l2 in lt2
on l1.ID equals l2.ID
orderby l1.ID
select new
{
ID = l1.ID,
Name = (l1.Name == l2.Name) ? "$" : (l2.Name + " (Modified)"),
Age = (l1.Age == l2.Age) ? "$" : (l2.Age + " (Modified)"),
Address = (l1.Address == l2.Address) ? "$" : (l2.Address + " (Modified)"),
ContactNo = (l1.ContactNo == l2.ContactNo) ? "$" : (l2.ContactNo + " (Modified)")
}).ToList();
// Displaying Records from List1 which is not in List2
var result1 = from l1 in lt1
where !(from l2 in lt2
select l2.ID).Contains(l1.ID)
orderby l1.ID
select new
{
ID = l1.ID,
Name = " Deleted",
Age = " Deleted",
Address = " Deleted",
ContactNo = " Deleted"
};
// Displaying Records from List1 which is not in List2
var result2 = from l1 in lt2
where !(from l2 in lt1
select l2.ID).Contains(l1.ID)
orderby l1.ID
select new
{
ID = l1.ID,
Name = l1.Name + " (Added)",
Age = l1.Age + " (Added)",
Address = l1.Address + " (Added)",
ContactNo = l1.ContactNo + " (Added)"
};
var res1 = result.Concat(result1).Concat(result2);
foreach (var item in res1)
{
Employee emp = new Employee();
//Response.Write(item + "<br/>");
emp.ID = item.ID;
emp.Name = item.Name;
emp.Age = item.Age;
emp.Address = item.Address;
emp.ContactNo = item.ContactNo;
lst.Add(emp);
}
}
return lst;
}
Here I am calling compareList method and returns the result and displaying it on the html table.
List<Employee> lt1 = new List<Employee>();
List<Employee> lt2 = new List<Employee>();
List<Employee> resultset = new List<Employee>();
//string value = "ID";
StringBuilder htmlTable = new StringBuilder();
htmlTable.Append("<table border='1'>");
htmlTable.Append("<tr><th>ID</th><th>Name</th><th>Age</th><th>Address</th><th>ContactNo</th></tr>");
resultset = ListCompare(lt1, lt2);
foreach(var item in resultset)
{
htmlTable.Append("<tr>");
htmlTable.Append("<td>" + item.ID + "</td>");
htmlTable.Append("<td>" + item.Name + "</td>");
htmlTable.Append("<td>" + item.Age + "</td>");
htmlTable.Append("<td>" + item.Address + "</td>");
htmlTable.Append("<td>" + item.ContactNo + "</td>");
htmlTable.Append("</tr>");
}
htmlTable.Append("</table>");
PlaceHolder1.Controls.Add(new Literal { Text = htmlTable.ToString() });
My question is how to generalize this coding. I may have any class(like Employee or Student). I want the coding just i will pass the two lists of objects to CompareMethod(to compare method i will pass any type of list of objects) which will return the list as result. How to proceed, pls give any idea.

If you are interesting in collection equality, I would like to recomend next stuff:
Enumerable.SequenceEqual
Determines whether two sequences are equal by comparing their elements by using a specified IEqualityComparer. MSDN
in case of unit testing:
CollectionAssert.AreEquivalent
Verifies that two specified collections are equivalent. The assertion fails if the collections are not equivalent. MSDN
if you need to know about difference:
Enumerable.Except
Produces the set difference of two sequences. MSDN

You can create your compare method as the following:
protected List<TResult> ListCompare<TKey, TInput, TResult>(List<TInput> lt1, List<TInput> lt2, Func<TInput, TKey> key, Func<TInput, TInput, TResult> modified, Func<TInput, TResult> added, Func<TInput, TResult> deleted)
{
// Displaying Matching Records from List1 and List2 by ID
var matchingEmployees = lt1.Join(lt2, key, key, modified);
// Displaying Records from List1 which is not in List2
var lt1NotInlt2 = lt1
.Where(e1 => !lt2.Any(e2 => key(e2).Equals(key(e1))))
.Select(deleted);
// Displaying Records from List2 which is not in List1
var lt2NotInlt1 = lt2
.Where(e2 => !lt1.Any(e1 => key(e1).Equals(key(e2))))
.Select(added);
return matchingEmployees.Concat(lt1NotInlt2).Concat(lt2NotInlt1).ToList();
}
If you don't want to use the key, then your compare method should look like this and your class should implement the Equals method:
protected List<TResult> ListCompare<TInput, TResult>(List<TInput> lt1, List<TInput> lt2, Func<TInput, TInput, TResult> modified, Func<TInput, TResult> added, Func<TInput, TResult> deleted)
{
// Displaying Matching Records from List1 and List2 by ID
var matchingEmployees = lt1
.Where(e1 => lt2.Any(e2 => e2.Equals(e1)))
.Select(e1 =>
{
var e2 = lt2.First(e => e.Equals(e1));
return modified(e1, e2);
});
// Displaying Records from List1 which is not in List2
var lt1NotInlt2 = lt1
.Where(e1 => !lt2.Any(e2 => e2.Equals(e1)))
.Select(deleted);
// Displaying Records from List2 which is not in List1
var lt2NotInlt1 = lt2
.Where(e2 => !lt1.Any(e1 => e1.Equals(e2)))
.Select(added);
return matchingEmployees.Concat(lt1NotInlt2).Concat(lt2NotInlt1).ToList();
}
Then you can call the compare method like this:
var result = ListCompare<int, Employee, Employee>(
lt1,
lt2,
e => e.ID,
(e1, e2) => new Employee
{
ID = e1.ID,
Name = (e1.Name == e2.Name) ? "$" : (e2.Name + " (Modified)"),
Age = (e1.Age == e2.Age) ? "$" : (e2.Age + " (Modified)"),
Address = (e1.Address == e2.Address) ? "$" : (e2.Address + " (Modified)"),
ContactNo = (e1.ContactNo == e2.ContactNo) ? "$" : (e2.ContactNo + " (Modified)")
},
e => new Employee
{
ID = e.ID,
Name = e.Name + " (Added)",
Age = e.Age + " (Added)",
Address = e.Address + " (Added)",
ContactNo = e.ContactNo + " (Added)"
},
e => new Employee
{
ID = e.ID,
Name = " Deleted",
Age = " Deleted",
Address = " Deleted",
ContactNo = " Deleted"
});

Related

How to get Index of IEnumerable SelectList?

I want index from ViewBag and if not possible then From selectedlist but can't get it.
ViewBag.Lst_Fetch_Record = new SelectList(list.OrderBy(ITEM_CD => ITEM_CD));
int index = ViewBag.Lst_Fetch_Record.IndexOf("I1");
Use this method :
ViewBag.Lst_Fetch_Record.Select((item, index) => new
{
...Your Code
}
Getting Index without using for loop
var result2 = new SelectList(list.OrderBy(ITEM_CD=> ITEM_CD)).ToList();
INT Index = result2.IndexOf(result2.Where(p => p.Text == a).FirstOrDefault());
This will give you an ordered list with indexes
List<string> selectListName = new List<String>();
selectListName.Add("Ohio");
selectListName.Add("Maine");
selectListName.Add("Texas");
selectListName.Add("Oregon");
selectListName.Add("Alabama");
var result2 = selectListName.Select( (state, index) => new { index, state
}).OrderBy(a=>a.state).ToList();
foreach(var b in result2)
{
Console.WriteLine( b.index + " " + b.state) ;
}
result: If you re looking for the existing index
4 Alabama
1 Maine
0 Ohio
3 Oregon
2 Texas
To use the result
Console.WriteLine(result2.FirstOrDefault(a=>a.state.Equals("Ohio")).index);
2
Console.WriteLine(result2.FirstOrDefault(a=>a.index.Equals(2)).state);
Ohio
To get this result:
0 Alabama
1 Maine
2 Ohio
3 Oregon
4 Texas
Order first, then index as shown below
var result2 = selectListName.OrderBy(a=>a).Select( (state, index) => new { index,
state }).ToList();
foreach(var b in result2)
{
Console.WriteLine( b.index + " " + b.state) ;
}
Check this example:
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void OrderByEx1()
{
Pet[] pets = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };
IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);
foreach (Pet pet in query)
{
Console.WriteLine("{0} - {1}", pet.Name, pet.Age);
}
}
Source: Microsoft documentation
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.orderby?view=net-5.0

Orderby not working

I am sorting on multiple criteria using dynamic sorting, here's my code:
public ActionResult WebGrid(int page = 1, int rowsPerPage = 10, string sortCol = "OrderID", string sortDir = "ASC", string sortSecCol = "OrderID", string sortSecDir = "ASC")
{
List<Orders> res;
using (var nwd = new NorthwindEntities())
{
var _res = nwd.Orders
.AsQueryable()
.OrderBy(sortCol + " " + sortDir, sortSecCol + " " + sortSecDir)
.Skip((page - 1) * rowsPerPage)
.Take(rowsPerPage)
.Select(o => new Orders
{
What I am trying to do in here is I want the column OrderID be the secondary sort whenever it is not a primary sort, but it didn't work when I actually selected other column as a primary sort.
In order words, when other column is select as primary sort in descending order, OrderID should also be in descending order, I am not sure what did I missed in my code.
The OrderBy method I used is come from here (MSDN).
The method you are using has the following signature:
public static IQueryable<T> OrderBy<T>(
this IQueryable<T> source,
string ordering,
params object[] values
)
so the sortSecCol + " " + sortSecDir goes to values argument, while the whole ordering is supposed to be provided as comma separated list in the ordering argument.
You can use something like this instead:
var ordering = sortCol + " " + sortDir;
if (sortSecCol != sortCol)
ordering += ", " + sortSecCol + " " + sortSecDir;
...
.OrderBy(ordering)
...
try this:
if (sortCol == "OrderID" && sortDir == "ASC")
{
_res = l.OrderBy(x => x.OrderId).ThenBy(x => x.AnotherField);
}
if (sortCol == "OrderID" && sortDir == "DESC")
{
_res = l.OrderByDescending(x => x.OrderId).ThenByDescending(x => x.AnotherField);
}
if (sortCol == "AnotherField" && sortDir == "ASC")
{
_res = l.OrderBy(x => x.AnotherField).ThenBy(x => x.OrderId);
}
if (sortCol == "AnotherField" && sortDir == "DESC")
{
_res = l.OrderByDescending(x => x.AnotherField).ThenByDescending(x => x.OrderId);
}
_res.Skip((page - 1) * rowsPerPage)
.Take(rowsPerPage)
.Select(o => new Orders
{

Linq: find similar objects from two different lists

I've got two separate lists of custom objects. In these two separate lists, there may be some objects that are identical between the two lists, with the exception of one field ("id"). I'd like to know a smart way to query these two lists to find this overlap. I've attached some code to help clarify. Any suggestions would be appreciated.
namespace ConsoleApplication1
{
class userObj
{
public int id;
public DateTime BirthDate;
public string FirstName;
public string LastName;
}
class Program
{
static void Main(string[] args)
{
List<userObj> list1 = new List<userObj>();
list1.Add(new userObj()
{
BirthDate=DateTime.Parse("1/1/2000"),
FirstName="John",
LastName="Smith",
id=0
});
list1.Add(new userObj()
{
BirthDate = DateTime.Parse("2/2/2000"),
FirstName = "Jane",
LastName = "Doe",
id = 1
});
list1.Add(new userObj()
{
BirthDate = DateTime.Parse("3/3/2000"),
FirstName = "Sam",
LastName = "Smith",
id = 2
});
List<userObj> list2 = new List<userObj>();
list2.Add(new userObj()
{
BirthDate = DateTime.Parse("1/1/2000"),
FirstName = "John",
LastName = "Smith",
id = 3
});
list2.Add(new userObj()
{
BirthDate = DateTime.Parse("2/2/2000"),
FirstName = "Jane",
LastName = "Doe",
id = 4
});
List<int> similarObjectsFromTwoLists = null;
//Would like this equal to the overlap. It could be the IDs on either side that have a "buddy" on the other side: (3,4) or (0,1) in the above case.
}
}
}
I don't know why you want a List<int>, i assume this is what you want:
var intersectingUser = from l1 in list1
join l2 in list2
on new { l1.FirstName, l1.LastName, l1.BirthDate }
equals new { l2.FirstName, l2.LastName, l2.BirthDate }
select new { ID1 = l1.id, ID2 = l2.id };
foreach (var bothIDs in intersectingUser)
{
Console.WriteLine("ID in List1: {0} ID in List2: {1}",
bothIDs.ID1, bothIDs.ID2);
}
Output:
ID in List1: 0 ID in List2: 3
ID in List1: 1 ID in List2: 4
You can implement your own IEqualityComparer<T> for your userObj class and use that to run a comparison between the two lists. This will be the most performant approach.
public class NameAndBirthdayComparer : IEqualityComparer<userObj>
{
public bool Equals(userObj x, userObj y)
{
return x.FirstName == y.FirstName && x.LastName == y.LastName && x.BirthDate == y.BirthDate;
}
public int GetHashCode(userObj obj)
{
unchecked
{
var hash = (int)2166136261;
hash = hash * 16777619 ^ obj.FirstName.GetHashCode();
hash = hash * 16777619 ^ obj.LastName.GetHashCode();
hash = hash * 16777619 ^ obj.BirthDate.GetHashCode();
return hash;
}
}
}
You can use this comparer like this:
list1.Intersect(list2, new NameAndBirthdayComparer()).Select(obj => obj.id).ToList();
You could simply join the lists on those 3 properties:
var result = from l1 in list1
join l2 in list2
on new {l1.BirthDate, l1.FirstName, l1.LastName}
equals new {l2.BirthDate, l2.FirstName, l2.LastName}
select new
{
fname = l1.FirstName,
name = l1.LastName,
bday = l1.BirthDate
};
Instead of doing a simple join on just one property (column), two anonymous objects are created new { prop1, prop2, ..., propN}, on which the join is executed.
In your case we are taking all properties, except the Id, which you want to be ignored and voila:
Output:
And Tim beat me to it by a minute
var similarObjectsFromTwoLists = list1.Where(x =>
list2.Exists(y => y.BirthDate == x.BirthDate && y.FirstName == x.FirstName && y.LastName == x.LastName)
).ToList();
This is shorter, but for large list is more efficient "Intersect" or "Join":
var similarObjectsFromTwoLists =
list1.Join(list2, x => x.GetHashCode(), y => y.GetHashCode(), (x, y) => x).ToList();
(suposing GetHashCode() is defined for userObj)
var query = list1.Join (list2,
obj => new {FirstName=obj.FirstName,LastName=obj.LastName, BirthDate=obj.BirthDate},
innObj => new {FirstName=innObj.FirstName, LastName=innObj.LastName, BirthDate=innObj.BirthDate},
(obj, userObj) => (new {List1Id = obj.id, List2Id = userObj.id}));
foreach (var item in query)
{
Console.WriteLine(item.List1Id + " " + item.List2Id);
}

slightly complex linq for C#

I asked a question before on retrieving the count of data server side and was provided a solution on the site. The suggestion was to use linq which worked perfectly however since i'm relatively new to it I need a little in depth help.
Using John's solution:
class Guy
{
public int age; public string name;
public Guy( int age, string name ) {
this.age = age;
this.name = name;
}
}
class Program
{
static void Main( string[] args ) {
var GuyArray = new Guy[] {
new Guy(22,"John"),new Guy(25,"John"),new Guy(27,"John"),new Guy(29,"John"),new Guy(12,"Jack"),new Guy(32,"Jack"),new Guy(52,"Jack"),new Guy(100,"Abe")};
var peeps = from f in GuyArray group f by f.name into g select new { name = g.Key, count = g.Count() };
foreach ( var record in peeps ) {
Console.WriteLine( record.name + " : " + record.count );
}
}
}
I can get the count of occurrences of John, Jake and Abe using the above as suggested by John. However what if the problem was a little more complicated for instance
var GuyArray = new Guy[] {
new Guy(22,"John", "happy"),new Guy(25,"John", "sad"),new Guy(27,"John", "ok"),
new Guy(29,"John", "happy"),new Guy(12,"Jack", "happy"),new Guy(32,"Jack", "happy"),
new Guy(52,"Jack", "happy"),new Guy(100,"Abe", "ok")};
The above code works great to retrieve the number of occurrences of the different names but what if I need the number of occurences of the names and also the number of occurrences of each person who is happy, sad or ok as well. ie output is : Name, count of names, count of names that are happy, count of names that are sad, count of names that are ok. If linq isn't the best solution for this, I am prepared to listen to all alternatives. Your help is much appreciated.
Frankly, it's not clear if you want the total number of people that are happy, or the total number of people that are happy by name (also for sad, ok). I'll give you a solution that can give you both.
var nameGroups = from guy in GuyArray
group guy by guy.name into g
select new {
name = g.Key,
count = g.Count(),
happy = g.Count(x => x.status == "happy"),
sad = g.Count(x => x.status == "sad"),
ok = g.Count(x => x.status == "ok")
};
Then:
foreach(nameGroup in nameGroups) {
Console.WriteLine("Name = {0}, Count = {1}, Happy count = {2}, Sad count = {3}, Okay count = {4}", nameGroup.name, nameGroup.count, nameGroup.happy, nameGroup.sad, nameGroup.ok);
}
If you want the total happy, sad, ok counts you can say:
Console.WriteLine(nameGroups.Sum(nameGroup => nameGroup.happy));
etc.
Additionally, you should make an enum
public enum Mood {
Happy,
Sad,
Okay
}
and then
class Guy {
public int Age { get; set; }
public string Name { get; set; }
public Mood Mood { get; set; }
}
so that you can instead write:
var people = from guy in guyArray
group guy by guy.Name into g
select new {
Name = g.Key,
Count = g.Count(),
HappyCount = g.Count(x => x.Mood == Mood.Happy),
SadCount = g.Count(x => x.Mood == Mood.Sad),
OkayCount = g.Count(x => x.Mood == Mood.Okay)
};
To do so:
class Guy
{
public int age; public string name; string mood;
public Guy( int age, string name,string mood ) {
this.age = age;
this.name = name;
this.mood = mood;
}
}
class Program
{
static void Main( string[] args ) {
var GuyArray = new Guy[] {
new Guy(22,"John", "happy"),new Guy(25,"John", "sad"),new Guy(27,"John", "ok"),
new Guy(29,"John", "happy"),new Guy(12,"Jack", "happy"),new Guy(32,"Jack", "happy"),
new Guy(52,"Jack", "happy"),new Guy(100,"Abe", "ok")};
var peepsSad = from f in GuyArray where f.mood=="sad" group f by f.name into g select new { name = g.Key, count = g.Count() };
var peepsHappy = from f in GuyArray where f.mood=="happy" group f by f.name into g select new { name = g.Key, count = g.Count() };
var peepsOk = from f in GuyArray where f.mood=="ok" group f by f.name into g select new { name = g.Key, count = g.Count() };
foreach ( var record in peepsSad ) {
Console.WriteLine( record.name + " : " + record.count );
}
foreach ( var record in peepsHappy ) {
Console.WriteLine( record.name + " : " + record.count );
}
foreach ( var record in peepsOk ) {
Console.WriteLine( record.name + " : " + record.count );
}
}
}

Can a single LINQ Query Expression be framed in this scenario?

I am facing a scenario where I have to filter a single object based on many objects.
For sake of example, I have a Grocery object which comprises of both Fruit and Vegetable properties. Then I have the individual Fruit and Vegetable objects.
My objective is this:
var groceryList = from grocery in Grocery.ToList()
from fruit in Fruit.ToList()
from veggie in Vegetable.ToList()
where (grocery.fruitId = fruit.fruitId)
where (grocery.vegId = veggie.vegId)
select (grocery);
The problem I am facing is when Fruit and Vegetable objects are empty.
By empty, I mean their list count is 0 and I want to apply the filter only if the filter list is populated.
I am also NOT able to use something like since objects are null:
var groceryList = from grocery in Grocery.ToList()
from fruit in Fruit.ToList()
from veggie in Vegetable.ToList()
where (grocery.fruitId = fruit.fruitId || fruit.fruitId == String.Empty)
where (grocery.vegId = veggie.vegId || veggie.vegId == String.Empty)
select (grocery);
So, I intend to check for Fruit and Vegetable list count...and filter them as separate expressions on successively filtered Grocery objects.
But is there a way to still get the list in case of null objects in a single query expression?
I think the LINQ GroupJoin operator will help you here. It's similar to the TSQL LEFT OUTER JOIN
IEnumerable<Grocery> query = Grocery
if (Fruit != null)
{
query = query.Where(grocery =>
Fruit.Any(fruit => fruit.FruitId == grocery.FruitId));
}
if (Vegetable != null)
{
query = query.Where(grocery =>
Vegetable.Any(veggie => veggie.VegetableId == grocery.VegetableId));
}
List<Grocery> results = query.ToList();
Try something like the following:
var joined = grocery.Join(fruit, g => g.fruitId,
f => f.fruitId,
(g, f) => new Grocery() { /*set grocery properties*/ }).
Join(veggie, g => g.vegId,
v => v.vegId,
(g, v) => new Grocery() { /*set grocery properties*/ });
Where I have said set grocery properties you can set the properties of the grocery object from the g, f, v variables of the selector. Of interest will obviouly be setting g.fruitId = f.fruitId and g.vegeId = v.vegeId.
var groceryList =
from grocery in Grocery.ToList()
join fruit in Fruit.ToList()
on grocery.fruidId equals fruit.fruitId
into groceryFruits
join veggie in Vegetable.ToList()
on grocery.vegId equals veggie.vegId
into groceryVeggies
where ... // filter as needed
select new
{
Grocery = grocery,
GroceryFruits = groceryFruits,
GroceryVeggies = groceryVeggies
};
You have to use leftouter join (like TSQL) for this. below the query for the trick
private void test()
{
var grocery = new List<groceryy>() { new groceryy { fruitId = 1, vegid = 1, name = "s" }, new groceryy { fruitId = 2, vegid = 2, name = "a" }, new groceryy { fruitId = 3, vegid = 3, name = "h" } };
var fruit = new List<fruitt>() { new fruitt { fruitId = 1, fname = "s" }, new fruitt { fruitId = 2, fname = "a" } };
var veggie = new List<veggiee>() { new veggiee { vegid = 1, vname = "s" }, new veggiee { vegid = 2, vname = "a" } };
//var fruit= new List<fruitt>();
//var veggie = new List<veggiee>();
var result = from g in grocery
join f in fruit on g.fruitId equals f.fruitId into tempFruit
join v in veggie on g.vegid equals v.vegid into tempVegg
from joinedFruit in tempFruit.DefaultIfEmpty()
from joinedVegg in tempVegg.DefaultIfEmpty()
select new { g.fruitId, g.vegid, fname = ((joinedFruit == null) ? string.Empty : joinedFruit.fname), vname = ((joinedVegg == null) ? string.Empty : joinedVegg.vname) };
foreach (var outt in result)
Console.WriteLine(outt.fruitId + " " + outt.vegid + " " + outt.fname + " " + outt.vname);
}
public class groceryy
{
public int fruitId;
public int vegid;
public string name;
}
public class fruitt
{
public int fruitId;
public string fname;
}
public class veggiee
{
public int vegid;
public string vname;
}
EDIT:
this is the sample result
1 1 s s
2 2 a a
3 3

Categories