Linq Expression to select items based on list - c#

I have a table with parentId field and childId field.I have to select the childId field data based on a list of parentId comparing with parentId field values.
here is the sample:
List<int> parents=new list(){1,2,4};
Table :
parentId childId
1 3
5 5
2 4
4 7
how can i select the childId using linq expression

var childId = child.Where(x => parents.Contains(x.parentId)).Select(x => x.childId).ToList();

var childId = yourTable.Where(m => parents.Contains(m.parentId)).Select(m => m.childId).ToList()

Related

EF duplicate values in secondary table

I'm developing a web application using Entity Framework.
I need do a select and pass values for an Ilist but it's returns duplicate values.
IQueryable<establishmentInfo> filter = (from x in db.establishments
join t in db.establishment_categories on x.id equals t.establishment
join q in db.categories on t.category equals q.id
where (x.name.ToUpper().Contains(search.ToUpper()))
select new establishmentInfo
{
id = x.id,
name = x.name,
id_category = q.id,
category = q.name,
});
IList<establishmentInfo>establishments = filter.ToList();
Establishment table
id name email
---------------------------
1 AAA a#a.com
2 BBB b#b.com
Establishment_categories
id establishment category
-------------------------------
1 1 1
2 1 2
3 2 1
Categories
id name
---------------------
1 alpha
2 beta
The problem is that return 2 establishments, one with category 1 and other with category 2. I need remove one of these.
Can anyone help?
As #NetMage said,your linq statement should return two values that are not repeated.
We can see that there are two records with establishment set to 1 in your Establishment_categories table. You can check your establishments. The id_category should be 1, the category should be alpha, the other should be id_categoryis 2, and the category should be beta.
You can see below image:
If you only want to get the first data of establishments, you can write the code as follows:
IQueryable<Establishment> filter = (from x in _context.Establishments
join t in _context.Establishment_Categories on x.Id equals t.EstablishmentId
join q in _context.Categories on t.CategoryId equals q.Id
where x.Name.ToUpper().Contains(search.ToUpper())
select new Establishment
{
Id = x.Id,
Name = x.Name,
CategoryId = q.Id,
CategoryName = q.Name,
}).Take(1);
List<Establishment> establishments = filter.ToList();
Result:
By the way, assuming that there are duplicates in your returned data, you can add the .Distinct() method after your linq to remove duplicates.

Using Where clause in Group Join

Please Consider these 2 tables:
CategoryID CategoryName CategoryModel
-----------------------------------------------------------
1 Book 1
2 Shoe 2
3 Glass 1
and
SubCategoryID SubCategoryName CategoryID SubCategoryModel OtherColumn1 OtherColum2
---------------------------------------------------------------------
1 Book1 1 3
2 Book2 1 1
3 Shoe1 2 2
4 Shoe2 2 2
I want such this query:
from a in Category
join b in SubCategory
on a.CategoryID equals b.CategoryID into grpDetail
where a.CategoryModel != b.SubCategoryModel <----------
select new
{
Id = a.CategoryID,
Count1 = grpDetail.Count(o=>o.OtherColumn1 == 1),
...
}
the problem id I can't access to b in above specifies line. How can I write this query?
Thanks
There is a straightforward one to many relation between Categories and SubCategories: every Category has zero or more SubCategories; every SubCategory belongs to exactly one Category, namely the Category that the foreign key SubCategory.CategoryId refers to.
You want to join Category and SubCategory on this foreign key. You don't want all Category-SubCategory combinations that match, you want only those where Category.CategoryModel is not equal to SubCategory.SubCategoryModel.
From the remaining records, you want to select several properties. I don't see property GrpDetail in your classes, so I don't know what you want.
Luckily you mention that your problem is in the Where:
var result = Categories.Join(SubCategories, // join tables Categories and SubCategories
category => category.Id, // from every category take the Id,
subCategory => subCategory.CategoryId, // from every subCategory take foreign key CategoryId
(category, subCategory) => new // when they match make one new object
{
// we need at least Category.CategoryModel and SubCategory.SubCategoryModel
CategoryModel = category.CategoryModel,
SubCategoryModel = subCategory.SubCategoryModel,
// Select other Category properties that you plan to use:
CategoryId = category.Id,
...
// Select other SubCategory properties that you plan to use:
...
})
// we don't want all combinations, only those where
// CategoryModel is not equal to SubCategoryModel
.Where(joinResult => joinResult.CategoryModel != joinResult.SubCategoryModel)
// from the remaining combinations calculate the final result
.Select(joinResult => new
{
Id = joinResult.CategoryId,
Count1 = ... // sorry, don't know what property grpDetail does
...
});
split your query into 2, first do your join with the where clause and then do your group by.

Finding a TOP LEVEL parent in Entity Framework Query

I have got two tables as following
Table Person
Id Name
1 A
2 B
3 C
4 D
5 E
Table RelationHierarchy
ParentId CHildId
2 1
3 2
4 3
This will form a tree like structure
D
|
C
|
B
|
A
ParentId and ChildId are foreign keys of Id column of Person Table
Let's suppose to EF entity Names are as Table names. I need to find top level Parent of Each person. Resultset should be as following
PersonId PersonName TopLevelPArentID TopLevelPArentName
Can anyone suggest any LINQ or LINQ to Entity Query?
The top parent would have ParentId set to NULL I assume?
Using that assumption we can go through each Person using a recursive function.
public YourMainFunction(){
List<Person> allPersons = entityContext.Person.ToList();
List<KeyValuePair<Person, Person>> personAndParents = new List<KeyValuePair<Person, Person>>();
foreach(Person p in allPersons){
personAndParents.Add(new KeyValuePair<Person, Person>(p, GetTopParent(p)));
}
}
//Now you have a list of each Persons Parents in a key/value pair list.
public Person GetTopParent(Person p){
if(p.RelationHierarchy.Count(r=>r.ParentId != null) == 0){
return p;
}
else{
return GetTopParent(p.RelationHierarchy.FirstOrDefault(r=>r.ParentId != null).Person1); //This should be the parent relation, not the child relation, im not sure what you have named the relations.
}
}

LINQ search records until parentid = 0

I have a C# List with 3 fields: ID, Name and ParentID. I am binding it to a treeview. Now I am also having a search feature where I want to filter the List and rebind the treeview.
If I search for child-1-1, my linq should be able to get following records: parent-1, child-1-1. So that I have to get records containing my search text and than get the record with ID as ParentID of this. All ParentIDs(roots) have ParentID value 0 so I have to keep on getting records until ParentID is 0.
Example of Data:
ID Name ParentID
1 parent-1 0
2 parent-2 0
3 child-1-1 1
4 child-1-2 1
5 child-2-1 2
So my question is how can I get a LINQ expression to get records like I described above?
I mean something like var mydata = from p in this.mylist where...???
assuming you have List<Node> myList where Node class with properties (Id, ParentId, ...) based on https://stackoverflow.com/a/7063002/1594178 variant for you
static IEnumerable<Node> Parents(this IEnumerable<Node> nodes, int startId)
{
Node node = nodes.Where(n => n.Id = startId).Single();
yield return node;
while (node.ParentId != 0)
{
node = nodes.Where(n => n.Id = node.ParentId).Single();
yield return node;
}
}
to populate mydata with parents of your child with id = 3 along with that child use
var mydata = mylist.Parents(3)

Recursive function to show hierarchial display using c#

I am having a table like this
ID Title Parentid
1 Level1 0
2 Level2 1
3 Level3 2
4 Level4 1
I want output in hierarchy model according to the parentid ,Id relationship as
Level1
->Level2->Level 3
-> Level4.
I am able to achieve like
level1
/\
level2 level4.
Here I am not getting level 3.
But i want the ouptut as shown in the first example using c#.
(Untested) Try:
;with RCTE as
(select id, title full_path from MyTable where ParentID = 0
union all
select m.id, r.full_path & '->' & m.title full_path
from MyTable m, RCTE r
where m.parentid = r.id)
select full_path from RCTE
Are all the parents defined before the children?
If so, you can use a Dictionary(int, List(Item)) (sorry about the parentheses, can't seem to get the angle brackets to work) where, say,
public class Item {
public int Id { get; set;}
public int ParentId { get; set;}
public string Title {get; set;}
}
IDictionary<int, List<Item>> CreateTree(IEnumerable<Item> nodeList){
var ret = new Dictionary<int, List<Item>>();
foreach (var item in items) {
if (!ret.ContainsKey(item.ParentId)) {
ret.Add(item.ParentId, new List<Item>());
}
ret[item.ParentId].Add(item);
}
return ret;
}
This will give (for the above data)
0 => level1
1 => level2, level4
2 => level3
If the parent ids are not guaranteed to be before the child ids, then you need to add in some tweaking to allow for orphans and then add then process them at the end.
Hope this helps,
Alan.
The recursion should be done inside of SQL Server using a Common Table Expression query (CTE). One query should be able to give the results and the "levels" which can then be parsed in C# without the need for recursion in code.
Here's a link with examples: (Mark's example also applies)
http://msdn.microsoft.com/en-us/library/ms186243.aspx

Categories

Resources