简体   繁体   中英

Linq EF Split Parent into multiple Parents

Using Entity Framework to query a database with a Parent table and Child table with a 1-n relationship:

public class Parent {
    public int id { get; set; }
    public IList<Child> Children { get; set; }
}

public class Child {
    public int id { get; set; }
}

Using EF, here's a quick sample query:

var parents = context.Parents;

Which returns:

parent id = 1, children = { (id = 1), (id = 2), (id = 3) }

What we need is for this to flatten into a 1-1 relationship, but as a list of parents with a single child each:

parent id = 1, children = { (id = 1) }
parent id = 1, children = { (id = 2) }
parent id = 1, children = { (id = 3) }

We're using an OData service layer which hits EF. So performance is an issue -- don't want it to perform a ToList() or iterate the entire result for example.


We've tried several different things, and the closest we can get is creating an anonymous type like such:

var results = from p in context.Parents
              from c in p.Children
              select new { Parent = p, Child = c }

But this isn't really what we're looking for. It creates an anonymous type of parent and child, not parent with child. So we can't return an IEnumerable<Parent> any longer, but rather an IEnumerable<anonymous> . The anonymous type isn't working with our OData service layer.

Also tried with SelectMany and got 3 results, but all of Children which again isn't quite what we need:

context.Parents.SelectMany(p => p.Children)

Is what we're trying to do possible? With the sample data provided, we'd want 3 rows returned -- representing a List each with a single Child. When normally it returns 1 Parent with 3 Children, we want the Parent returned 3 times with a single child each.

Your requirements don't make any sense, the idea behind how EF and LINQ work is not those repetitive info like SQL does. But you know them better and we don't know the whole picture, so I will try to answer your question hoping I understood it correctly.

If like you said, your problem is that IEnumerable<anonymous> doesn't work with your OData service layer, then create a class for the relationship:

public class ParentChild {
    public Parent Parent { get; set; }
    public Child Child { get; set; }
}

And then you can use in in your LINQ query:

var results = from p in context.Parents
              from c in p.Children
              select new ParentChild { Parent = p, Child = c }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM