Question is How do a return a List of B with all the entities in children of all Parents without resorting to the type of code below, I was thinking u must be able to acheive the same within a single linq query?
Class Parent {
public Title,
public children List<B>,
}
data = List<A>
var childLists = from x in x.Parents select x.children;
List<B> output = new List<B>();
foreach (List<B> b in childLists)
output.AddRange(b);
Thanks.
List<B> allChildren = x.Parents.SelctMany(p => p.children).ToList()
var output = x.Parents.SelectMany(p => p.children).ToList();
using nesting
from parent in x.Parents
from child in parent.Children
select child;
Related
I am trying to create a tree from a somewhat large list of 13883 objects using Linq to sort the objects into their parent and child groups, each object is associated with a parentId, I can group the objects together using
var sortedList = marketItems.GroupBy(p => p.parentId).Select(grp => grp.ToList()).ToList();
but this only sorts them into groups, I'm not yet fluent with linq and cant figure out how to map the children correctly. the null ParentGroup is the top level of the tree. Anyone with more experience with linq able to offer some ideas on how to group the llist correctly.
public JsonResult GetJsTree3Data()
{
var marketItems = new List<JsTree3Node>();
var itemList = new List<JsTree3Node>();
foreach (var group in GenerateGroups(connString))
{
var node = JsTree3Node.NewNode(group.id_str);
node.text = group.name;
node.state = new State(false, false, false);
node.parentId = group.marketParentGroup;
marketItems.Add(node);
}
foreach (var group in GenerateItems(connString))
{
var node = JsTree3Node.NewNode(group.id_str);
node.text = group.name;
node.state = new State(false, false, false);
node.parentId = group.marketParentGroup;
marketItems.Add(node);
}
// Create our root node and ensure it is opened
var root = new JsTree3Node()
{
id = "0",
text = "Market Items",
state = new State(true, false, false)
};
var sortedList = marketItems.GroupBy(u => u.parentId).Select(grp => grp.ToList()).ToList();
root.children = sortedList;
return Json(root, JsonRequestBehavior.AllowGet);
}
The final result I am trying achive is a tree of items that users can choose from. there is only one level of the tree as the children arent ordered in the sorted list
I see, the parents can contain multiple items: I believe this is what you are looking for:
var sortedList = from p in marketItems
group p by p.ParentGroup into Groups
select Groups;
//to access the items in each group individually
foreach (var grouping in sortedList)
{
foreach (var Item in grouping)
{
Item.Description///you can access the individual items from this layer...
}
}
Your code should do this, but to access the grouping items you need to use a nested foreach loop.
I'm not sure what your end goal is, but I'm not sure if what you're trying to do can be strictly done with a single LINQ pass. If it were possible, though, I imagine that it would be quite convoluted. You can do it in two LINQ queries quite simply, though:
var refDict = marketItems.ToDictionary(k => k.Id, v => v);
var groupedList = marketItems.Select(s =>
new
{
Parent = s.ParentGroup == null ? null : refDict[s.ParentGroup],
Child = s
}).ToList();
Then use it like this:
var parent = groupedList[0].Parent;
var child = groupedList[0].Child;
In all honesty, though, you could just keep yourself to the first line of code then query the dictionary for an object's parent yourself if you ever need it.
I have a list of objects which contains a list of other objects.
List<Parent> Ps;
Parent:
class Parent
{
List<Childs> Cs;
}
Is there a possibility to create with Linq a list of tuples of parents and childs?
Tuple<Parent, Child>
You can use Enumerable.SelectMany:
List<Tuple<Parent, Child>> parentChilds = Ps
.SelectMany(p => p.Cs.Select(c => Tuple.Create(p, c)))
.ToList();
This is equal to this:
var pcQuery = from parent in Ps
from child in parent.Cs
select Tuple.Create(parent, child);
List<Tuple<Parent, Child>> parentChilds = pcQuery.ToList();
var tuples = from p in Ps from c in p.Cs select Tuple.Create(p, c);
I have a database that is mapped using the Entity Framework. Entity Framework is generating the C# code of the database objects in the similar manner as shown below. For simplicity I have created Parent, Child, GrandChild hierarchy but the actual db contains much longer hierarchies and many other fields.
class Parent
{
string name;
int id;
datetime DateOfBirth;
}
class Child
{
string name;
int id;
int ParentId; ( FK reference to Parent Child )
}
class GrandChild
{
string name;
int id;
int ChildId; (FK reference to Child )
}
Now, I am building an api where the filters will be provided at runtime. I mean, some of the queries could be
Give all GrandChild rows for ParentId =1
Give All Grandchild rows for ChildName = "x"
Give all GrandChild rows for Parent with DateOfbirth = "x/y/z"
So, how can I build in C# code, using LINQ or Expression Trees to create predicates and join filters dynamically/runtime.
Following URL:
https://msdn.microsoft.com/library/bb882637.aspx
shows how to create dynamic query, but not how to INNER JOIN multiple such queries. Does anyone know how to do that?
This Stackoverflow answer:
The parameter '***' was not bound in the specified LINQ to Entities query expression
also highlights how to create filters dynamically but not how to join them.
Does anyone know how to create dynamic queries to filter rows and join the queries? Let me know if you need more information. Thanks
Well, I'm going to suppose that is not your real model because you should have properties instead fields and your entities must be public.
If you have represented your db relationships using navigation properties, you could create a extension method like this:
static IQueryable<TEntity> Select<TEntity>(this IQueryable<TEntity> query, List<Expression<Func<TEntity, bool>>> filters = null,
List<Expression<Func<TEntity, object>>> includes = null)
{
if (includes != null)
{
query = includes.Aggregate(query, (current, include) => current.Include(include));
}
if (filters != null)
{
query = filters.Aggregate(query, (current, filter) => current.Where(filter)); //at the end this is going to be translated to condition1 && condition2 ...
}
return query;
}
In the first list you pass all the conditions you want to apply to your query and the second helps you to load the related entities that you need in your query:
var conditions = new List<Expression<Func<GrandChild, bool>>>() { (t) => t.Child.Parent.ParentId==1 };
var includes = new List<Expression<Func<GrandChild, object>>>() { (t) => t.Child.Parent };
var query= yourContext.GrandChilds.Select(filters,includes);
1 . Give all GrandChild rows for ParentId =1
var grandChildData=from grand in GrandChild
join ch in Child on grand.ChildId equals ch.Id
where ch.ParentId==1
select grand;
Give All Grandchild rows for ChildName = "x"
var grandChildData=from grand in GrandChild
join ch in Child on grand.ChildId equals ch.Id
where ch.name = "x"
select grand;
Give all GrandChild rows for Parent with DateOfbirth = "x/y/z"
var grandChildData=from grand in GrandChild
join ch in Child on grand.ChildId equals ch.Id
join p in Parent on ch.ParentId equals p.id
where p.DateOfbirth==Convert.ToDateTime("2016/01/01")
select grand;
I have a class which has a collection
public class Parent
{
...
ISet<Child> Children;
...
}
Given a list of child names, I'd like to return parents whose Children property contains all items of this list.
I managed to write an HQL query, but it works for a single name, not a whole list :
SELECT p FROM Parent AS p JOIN p.Children AS c WHERE c.Name = 'MyName'
Thanks Mauricio, I managed to solve this problem with the following criteria query
var criteria = session.CreateCriteria<Parent>("p")
.Add(Restrictions.IsNotEmpty("p.Children"));
foreach (var name in namesToMatch)
{
criteria.Add(Subqueries.Exists(DetachedCriteria.For<Parent>("p2")
.SetProjection(Projections.Id())
.CreateAlias("p2.Children", "c")
.Add(Restrictions.Eq("c.Name", name))
.Add(Restrictions.EqProperty("p2.Id", "p.Id"))));
}
I have a self referential table, which has ID, ParentID (nullable).
So, the table contains many nodes, each node could be the root in the hierarchy (parent is null), or any level of the hierarchy (parent exists elsewhere in the table).
Given an arbitrary starting node, is there an elegant linq query that will return all children of the hierarchy from that node?
Thanks.
If you want to select all direct children of a node, a simple query like the following should do the job:
from item in table
where item.ID == parentID;
select item
If you want to select all descendants of a node, this is not possible with LINQ, because it requires recursion or a stack which LINQ (and SQL) doesn't provide.
See also:
StackOverflow: LINQ to SQL for self-referencing tables?
CodeProject: T-SQL - How to get all descendants of a given element in a hierarchical table
StackOverflow: Expressing recursion in LINQ
Here is a quick one I just wrote:
class MyTable
{
public int Id { get; set; }
public int? ParentId { get; set; }
public MyTable(int id, int? parentId) { this.Id = id; this.ParentId = parentId; }
}
List<MyTable> allTables = new List<MyTable> {
new MyTable(0, null),
new MyTable(1, 0),
new MyTable(2, 1)
};
Func<int, IEnumerable<MyTable>> f = null;
f = (id) =>
{
IEnumerable<MyTable> table = allTables.Where(t => t.Id == id);
if (allTables
.Where(t => t.ParentId.HasValue && t.ParentId.Value == table
.First().Id).Count() != 0)
return table
.Union(f(
allTables.Where(t => t.ParentId.HasValue && t.ParentId.Value == table
.First().Id).First().Id));
else return table;
};
But I believe it is possible to do using SQL with a Union ALL.
I know this is an old post but you should check out this extension:
http://www.scip.be/index.php?Page=ArticlesNET23
I've been using it and it is working great.
Basically I'm going with something like this as discussed in the SO link you proivded.
public IQueryable GetCategories(Category parent)
{
var cats = (parent.Categories);
foreach (Category c in cats )
{
cats = cats .Concat(GetCategories(c));
}
return a;
}
CTEs are probably the best solution but I'd like to keep things all in the same tier for now.