Join two arrayList based on key using c# - c#

I have two arrayList here here:
List<ArrayList1> data = new List<ArrayList1>() {
{ id = 1, name = "John Doe", age = 20 },
{ id = 2, name = "Mae Doe", age = 17 },
{ id = 3, name = "Mark Smith", age = 35 },
{ id = 4, name = "Selena Smith", age = 15 },
{ id = 5, name = "Shane Doe", age = 26 },
{ id = 6, name = "Will Smith", age = 45 }
};
List<ArrayList2> data = new List<ArrayList2>() {
{ id = 1, address = "Singapore", phone_number = "123", store_name = "ABC" },
{ id = 4, address = "Japan", phone_number = "456", store_name = "DEF" },
{ id = 5, address = "Korea", phone_number = "789", store_name = "GHI" }
};
I want to join them, kind of left join in mysql so the result will be like this
List<ArrayListResult> data = new List<ArrayListResult>() {
{ id = 1, name = "John Doe", age = 20, address = "Singapore", phone_number = "123", store_name = "ABC" },
{ id = 2, name = "Mae Doe", age = 17 },
{ id = 3, name = "Mark Smith", age = 35 },
{ id = 4, name = "Selena Smith", age = 15, address = "Japan", phone_number = "456", store_name = "DEF" },
{ id = 5, name = "Shane Doe", age = 26, address = "Korea", phone_number = "789", store_name = "GHI" },
{ id = 6, name = "Will Smith", age = 45 }
};
The address, phone_number, store_name will be merged to List based on the matched id.
Is there easy way of merging 2 arrayList in c# based on matched id? Please help. Thanks!

You're looking for this:
result =
(
from d1 in data1
join d2 in data2 on d1.id equals d2.id into gds
from gd in gds.DefaultIfEmpty()
select new ArrayListResult()
{
id = d1.id,
name = d1.name,
age = d1.age,
address = gd?.address,
phone_number = gd?.phone_number,
store_name = gd?.store_name,
}
).ToList();
That gives me:

Related

How to generate treeview using Linq

I have the following three tables,
Region Table,
RegionId
RegionName
1
Admin
2
North Region
3
South Region
Branch Table
BranchId
BranchName
FkRegionId
1
Roswell Rd
3
2
Test
2
3
Piedmont Ave
2
4
Ashford Dunwoody
1
User Table
UserId
FirstName
FkBranchId
1
Hasa
9
2
Jane
1
3
Joyce
7
4
Jane
1
5
John
3
6
Sharon
8
As mentioned above, each branch has its region and each user has a branch. I need to create following JSON for my frond-end usage. Therefore I need to populate data in order to create this JSON.
Region1
Branch1
Jane
Paul
Alex
Branch2
Neil
Kaja
Alex
Region2
Branch4
Ama
Hema
Ira
Branch5
Laura
Tim
Yea
How can I do this using C# and linq?
You need to use Linq Join and GroupBy as following:
var regions = new List<Region>()
{
new Region() { RegionId = 1, RegionName = "Admin" },
new Region() { RegionId = 2, RegionName = "North Region" },
new Region() { RegionId = 3, RegionName = "South Region" }
};
var branchs = new List<Branch>()
{
new Branch() {BranchId = 1, BranchName = "Roswell Rd", FkRegionId = 3},
new Branch() {BranchId = 2, BranchName = "Test", FkRegionId = 2},
new Branch() {BranchId = 3, BranchName = "Piedmont Ave ", FkRegionId = 2},
new Branch() {BranchId = 4, BranchName = "Ashford Dunwoody ", FkRegionId = 1},
};
var users = new List<User>()
{
new User() {UserId = 1, FirstName = "Hasa", FkBranchId = 9},
new User() {UserId = 2, FirstName = "Jane", FkBranchId = 1},
new User() {UserId = 3, FirstName = "Joyce", FkBranchId = 7},
new User() {UserId = 4, FirstName = "Jane", FkBranchId = 1},
new User() {UserId = 5, FirstName = "John", FkBranchId = 3},
new User() {UserId = 6, FirstName = "Sharon", FkBranchId = 8},
};
var tree = from user in users
join branch in branchs on user.FkBranchId equals branch.BranchId
join region in regions on branch.FkRegionId equals region.RegionId
group region by new { region.RegionId, branch.BranchId } into grp
select new
{
RegionName = regions.FirstOrDefault(s => s.RegionId == grp.Key.RegionId).RegionName,
Branchs = new
{
BranchName = branchs.FirstOrDefault(s => s.FkRegionId == grp.Key.RegionId).BranchName,
Users = users.Where(i => i.FkBranchId == grp.Key.BranchId).Select(s => new
{
FirstName = s.FirstName
})
}
};
var json = JsonConvert.SerializeObject(tree, Formatting.Indented);
This will give you an expected result:
[
{
"RegionName": "South Region",
"Branchs": {
"BranchName": "Roswell Rd",
"Users": [
{
"FirstName": "Jane"
},
{
"FirstName": "Jane"
}
]
}
},
{
"RegionName": "North Region",
"Branchs": {
"BranchName": "Test",
"Users": [
{
"FirstName": "John"
}
]
}
}
]
var jsonResponse = "[{\"UserId\":195,\"FirstName\":\"Carlton\",\"BranchId\":4,\"BranchName\":\"Test\",\"RegionId\":1,\"RegionName\":\"Admin\"},{\"UserId\":223,\"FirstName\":\"Lorenza\",\"BranchId\":4,\"BranchName\":\"Test\",\"RegionId\":1,\"RegionName\":\"Admin\"},{\"UserId\":163,\"FirstName\":\"Alice\",\"BranchId\":17,\"BranchName\":\"Ratnapura\",\"RegionId\":1,\"RegionName\":\"Admin\"},{\"UserId\":264,\"FirstName\":\"Karen\",\"BranchId\":7,\"BranchName\":\"Peachtree\",\"RegionId\":3,\"RegionName\":\"South Region\"},{\"UserId\":266,\"FirstName\":\"Starla\",\"BranchId\":7,\"BranchName\":\"Peachtree\",\"RegionId\":3,\"RegionName\":\"South Region\"},{\"UserId\":30,\"FirstName\":\"Jane\",\"BranchId\":9,\"BranchName\":\"Henderson Mill\",\"RegionId\":3,\"RegionName\":\"South Region\"}]";
var myDeserializedClass = JsonConvert.DeserializeObject < List < Root >> (jsonResponse);
var jsonResponseList = myDeserializedClass.GroupBy(item = >item.RegionId).Select(grp = >grp.GroupBy(item = >item.BranchId)).Select(grp = >grp.Select(innerg = >innerg.GroupBy(item = >item.UserId))).ToList();
var serializer = JsonConvert.SerializeObject(jsonResponseList, Formatting.Indented);
Root class
public class Root
{
public int UserId { get; set; }
public string FirstName { get; set; }
public int BranchId { get; set; }
public string BranchName { get; set; }
public int RegionId { get; set; }
public string RegionName { get; set; }
}
and the output:
[
[
[
[
{
"UserId": 195,
"FirstName": "Carlton",
"BranchId": 4,
"BranchName": "Test",
"RegionId": 1,
"RegionName": "Admin"
}
],
[
{
"UserId": 223,
"FirstName": "Lorenza",
"BranchId": 4,
"BranchName": "Test",
"RegionId": 1,
"RegionName": "Admin"
}
]
],
[
[
{
"UserId": 163,
"FirstName": "Alice",
"BranchId": 17,
"BranchName": "Ratnapura",
"RegionId": 1,
"RegionName": "Admin"
}
]
]
],
[
[
[
{
"UserId": 264,
"FirstName": "Karen",
"BranchId": 7,
"BranchName": "Peachtree",
"RegionId": 3,
"RegionName": "South Region"
}
],
[
{
"UserId": 266,
"FirstName": "Starla",
"BranchId": 7,
"BranchName": "Peachtree",
"RegionId": 3,
"RegionName": "South Region"
}
]
],
[
[
{
"UserId": 30,
"FirstName": "Jane",
"BranchId": 9,
"BranchName": "Henderson Mill",
"RegionId": 3,
"RegionName": "South Region"
}
]
]
]
]
If these are physically related tables then EF has taken care of it already. Just make sure your lazy loading is ON or you can eager load data as well by using include and then display data as it is. If you want to eager load information then try this query
using(var db = new DBContext){
var result = db.region.include(x => x.branches).theninclude(x => x.users).toList();
}
result will contain all of your data then bind that data into your custom define DTOs or you can directly bind entity models into views.
Its an overview of the code you can have your own implementation.
If there is no physical relations in between tables then use join using linq here is the link you can follow how joins works in linq.
link

Find an Object that contains a string in a list of strings using LINQ

I have these lists:
List<Author> MyAuthorList = new List<Author>();
List<string> BookListNo1 = new List<string>() { "The Girl with the Dragon Tattoo", "The Name of the Rose", "The Alienist", "In Cold Blood", "The Firm" };
List<string> BookListNo2 = new List<string>() { "And Then There Were None", "Mystic River", "The Shadow of the Wind", "Angels & Demons" , "The Big Sleep", "The Pelican Brief" };
List<string> BookListNo3 = new List<string>() { "One for the Money", "The Maltese Falcon", "In the Woods", "Presumed Innocent", "The Thirteenth Tale", "A is for Alibi", "Postmortem" };
List<string> BookListNo4 = new List<string>() { "Midnight in the Garden of Good and Evil", "The Strange Case of Dr. Jekyll and Mr. Hyde", "A Time to Kill", "The Historian" };
MyAuthorList.Add(new Author() { FirstName = "John", LastName = "Smith", Address = "Germany", Age = 13, NumberOfBooks = 5, EMBG = 123123, Books = BookListNo1, BankAccount = 1111, BankName = "Stupid Bank Name", BankAddress = "No One Knows" });
MyAuthorList.Add(new Author() { FirstName = "Max", LastName = "Warren", Address = "France", Age = 32, NumberOfBooks = 6, EMBG = 321321, Books = BookListNo2, BankAccount = 2222, BankName = "Stupid Bank Name", BankAddress = "Near The Bakery" });
MyAuthorList.Add(new Author() { FirstName = "Quinn", LastName = "Swanson", Address = "Russia", Age = 11, NumberOfBooks = 7, EMBG = 456456, Books = BookListNo3, BankAccount = 3333, BankName = "Stupid Bank Name", BankAddress = "On Some Desert Island" });
MyAuthorList.Add(new Author() { FirstName = "Ben", LastName = "Chaplin", Address = "Indonesia", Age = 34, NumberOfBooks = 4, EMBG = 654654, Books = BookListNo4, BankAccount = 4444, BankName = "Stupid Bank Name", BankAddress = "Moskovska 45" });
MyAuthorList.Add(new Author() { FirstName = "Jack", LastName = "Smirnoff", Address = "Germany", Age = 35, NumberOfBooks = 6, EMBG = 789789, Books = BookListNo2, BankAccount = 5555, BankName = "Stupid Bank Name 2", BankAddress = "Moskovska 452" });
Now I need to find all Authors from Germany with books that have the words "Girl" and "Blood" in them.
This is what I have tried so far:
I get all the authors from Germany like this:
var germanAuthors = MyAuthorList.Where(x => x.Address.Contains("Germany"));
..and all the books that have the words "Blood" and "Girl" in them like this:
var BooksOfAuthorsFromGermany = MyAuthorList.Where(x => x.Address.Contains("Germany")).SelectMany(y => y.Books);
List<string> words = new List<string> { "Blood", "Girl"};
var searchedListOfBooks = BooksOfAuthorsFromGermany.Where(s => words.Any(w => s.Contains(w)));
However, I can't combine these two together.
Do I need to do this in a completely different way?
Try this
var BooksOfAuthorsFromGermany = MyAuthorList
.Where(x => x.Address.Contains("Germany")
&& x.Books.Where(a => a.Contains("Girl")
|| a.Contains("Blood")).Count() > 0)
.ToList();
You can combine two query as follows ,
List<string> words = new List<string> { "Blood", "Girl"};
var AuthorList = MyAuthorList.Where(x => x.Address.Contains("Germany") && x.Books.Any(a => words.Any(w=> a.Contains(w)))).ToList();
According to your requirement you can use this
var germanAuthors = MyAuthorList.Where(x => x.Address.Contains("Germany") && x.Books.Any(y => y.Contains("Blood") && y.Contains("Girl"))).Select(Z => Z.FirstName);
var germanAuthorsWithBloodOrGirl = MyAuthorList.Where(x => x.Address.Contains("Germany") && x.Books.Any(y => y.Contains("Blood") || y.Contains("Girl"))).Select(Z => Z.FirstName);

When we Seed a database in ASP.NET MVC, why do we use a lamba expression for returning the id of elements?

In all the examples I see, such as
protected override void Seed(BookService.Models.BookServiceContext context)
{
context.Authors.AddOrUpdate(x => x.Id,
new Author() { Id = 1, Name = "Jane Austen" },
new Author() { Id = 2, Name = "Charles Dickens" },
new Author() { Id = 3, Name = "Miguel de Cervantes" }
);
context.Books.AddOrUpdate(x => x.Id,
new Book() { Id = 1, Title = "Pride and Prejudice", Year = 1813, AuthorId = 1,
Price = 9.99M, Genre = "Comedy of manners" },
new Book() { Id = 2, Title = "Northanger Abbey", Year = 1817, AuthorId = 1,
Price = 12.95M, Genre = "Gothic parody" },
new Book() { Id = 3, Title = "David Copperfield", Year = 1850, AuthorId = 2,
Price = 15, Genre = "Bildungsroman" },
new Book() { Id = 4, Title = "Don Quixote", Year = 1617, AuthorId = 3,
Price = 8.95M, Genre = "Picaresque" }
);
}
from here, I see that there is a lamba expression as the first parameter of the AddOrUpdate and it's always shown as the Id (primary key?) of the table. Can someone explain what that lamba expression is for? Is it for checking whether the Id is null? I'm confused.
It's to define which property should be checked to see if the Seed()-method should UPDATE or INSERT. In this case, if the given ID is already in the database, it will not insert it again (but update the existing entry).
But you could also check on Title, Year, ... or other properties to define if the entry should be inserted or updated in your database. Basically it's to prevent duplicates in your database, but you can give meaning to what a duplicate is to you.

How to creat a new list from existing list with elements which contains the same id in Linq to object?

I have a list:
var list = new List<Test>{
new Test = {
ID = 1,
Name = "Test 1",
RefId = 1
RefName = "Test RefName 1"
},
new Test = {
ID = 2,
Name = "Test 2",
RefId = 1
RefName = "Test RefName 1"
},
new Test = {
ID = 3,
Name = "Test 3",
RefId = 2
RefName = "Test RefName 2"
},
new Test = {
ID = 4,
Name = "Test 4",
RefId = 2
RefName = "Test RefName 2"
}
};
And I want to convert the top list into the new list:
var list = new List<TestNew>{
new TestNew = {
RefId = 1,
RefName = "Test RefName 1",
ListGroup = new List<Group>{
new Group{
ID = 1,
Name = "Test 1"
},
new Group{
ID = 2,
Name = "Test 2"
},
}
},
new TestNew = {
RefId = 2,
RefName = "Test RefName 2",
ListGroup = new List<Group>{
new Group{
ID = 3,
Name = "Test 3"
},
new Group{
ID = 4,
Name = "Test 4"
},
}
}
};
list.GroupBy(x => new { x.RefId, x.RefName })
.Select(g => new TestNew() {
RefId = g.Key.RefId,
RefName = g.Key.RefName,
ListGroup = g.Select(y => new Group() {
ID = y.ID,
Name = y.Name
}).ToList()
}).ToList();
Something like this should do the trick:
list.GroupBy(item => item.RefId)
.Select(grouping => new ListNew() {
RefId = grouping.Key,
RefName = grouping.First().RefName,
ListGroup = grouping.Select(i => new Group() { ID = i.ID, Name = i.Name }).ToList()
})
.ToList();
This does assume that the RefName/RefId are always consistant.

Split a List of an Object group by some properties with lambda expression

This is My Type:
public class MyObj {
public long Number { get; set; }
public string Name { get; set; }
public string Message { get; set; }
public DateTime RegisterDate { get; set; }
}
So I have a list of Myobj And I need to split the list to some lists where the objects of Name and Number of objects are equal, some thing like grouped by Name and Number:
assume this Sample:
List<MyObj> MyObjects = new List<MyObj>{
new MyObj() { Number = 1, Name = "BMW", Message = "msg1", RegisterDate = DateTime.Now },
new MyObj() { Number = 1, Name = "BMW", Message = "msg2", RegisterDate = DateTime.Now },
new MyObj() { Number = 1, Name = "BMW", Message = "msg3", RegisterDate = DateTime.Now },
new MyObj() { Number = 1, Name = "Honda", Message = "msg11", RegisterDate = DateTime.Now },
new MyObj() { Number = 1, Name = "Honda", Message = "msg12", RegisterDate = DateTime.Now },
new MyObj() { Number = 2, Name = "BMW", Message = "msg22", RegisterDate = DateTime.Now },
new MyObj() { Number = 2, Name = "BMW", Message = "msg23", RegisterDate = DateTime.Now },
new MyObj() { Number = 2, Name = "BMW", Message = "msg24", RegisterDate = DateTime.Now },
new MyObj() { Number = 2, Name = "Honda", Message = "msg30", RegisterDate = DateTime.Now },
new MyObj() { Number = 3, Name = "BMW", Message = "msg41", RegisterDate = DateTime.Now },
new MyObj() { Number = 3, Name = "BMW", Message = "msg42", RegisterDate = DateTime.Now },
new MyObj() { Number = 3, Name = "Ford", Message = "msg51", RegisterDate = DateTime.Now },
new MyObj() { Number = 3, Name = "Ford", Message = "msg52", RegisterDate = DateTime.Now },
new MyObj() { Number = 3, Name = "Ford", Message = "msg53", RegisterDate = DateTime.Now }
};
So I need a List<List<MyObj>> :
List<MyObj> MyObjectwith1AndBMW = new List<MyObj> {
new MyObj() { Number = 1, Name = "BMW", Message = "msg1", RegisterDate = DateTime.Now },
new MyObj() { Number = 1, Name = "BMW", Message = "msg2", RegisterDate = DateTime.Now },
new MyObj() { Number = 1, Name = "BMW", Message = "msg3", RegisterDate = DateTime.Now }
};
List<MyObj> MyObjectWith1AndHonda = new List<MyObj> {
new MyObj() { Number = 1, Name = "Honda", Message = "msg11", RegisterDate = DateTime.Now },
new MyObj() { Number = 1, Name = "Honda", Message = "msg12", RegisterDate = DateTime.Now }
};
List<MyObj> MyObjectWith2AndBMW = new List<MyObj> {
new MyObj() { Number = 2, Name = "BMW", Message = "msg22", RegisterDate = DateTime.Now },
new MyObj() { Number = 2, Name = "BMW", Message = "msg23", RegisterDate = DateTime.Now },
new MyObj() { Number = 2, Name = "BMW", Message = "msg24", RegisterDate = DateTime.Now }
};
List<MyObj> MyObjectWith2AndHonda = new List<MyObj> {
new MyObj() { Number = 2, Name = "Honda", Message = "msg30", RegisterDate = DateTime.Now }
};
List<MyObj> MyObjectwith3AndBMW = new List<MyObj> {
new MyObj() { Number = 3, Name = "BMW", Message = "msg41", RegisterDate = DateTime.Now },
new MyObj() { Number = 3, Name = "BMW", Message = "msg42", RegisterDate = DateTime.Now }
};
List<MyObj> MyObjectWith3AndFord = new List<MyObj> {
new MyObj() { Number = 3, Name = "Ford", Message = "msg51", RegisterDate = DateTime.Now },
new MyObj() { Number = 3, Name = "Ford", Message = "msg52", RegisterDate = DateTime.Now },
new MyObj() { Number = 3, Name = "Ford", Message = "msg53", RegisterDate = DateTime.Now }
};
the result is :
List<List<MyObj>> result = new List<List<MyObj>> {
MyObjectwith1AndBMW,
MyObjectWith1AndHonda,
MyObjectWith2AndBMW,
MyObjectWith2AndHonda,
MyObjectwith3AndBMW,
MyObjectWith3AndFord
};
SO what is your suggestion? How can I find list of MyObj with same the equal names and equal numbers?
List<List<MyObj>> result = MyObjects.GroupBy(m => new { m.Name, m.Number })
.Select(g => g.ToList())
.ToList();
var groups = (from row in MyObjects
group row by new { row.Number, row.Name } into grp
select grp.ToList()).ToList();
which is a List<List<MyObj>> grouped by .Number and .Name (together).

Categories

Resources