Entity Framework - Include in sub query? - Part 2

2019-07-16 11:30发布

I'm not sure if this is the right thing to do, I'm sure someone will tell me if it's not.

I asked a question (Entity Framework - Include in sub query?) earlier this evening, which was answered very well and has solved my problem. But, I think there could be a better way, so I'm going to re-ask the question, but slightly differently.

Let's say I have 3 tables:

Restaurant 1.....M MenuCategory 1.....M MenuItem I have a L2E query that looks something like this:

Restaurant = context.Restaurant .Include(r => r.MenuCategory) .FirstOrDefault(r => r.RestaurantId == resaurantId); Which works to some extent, but it only pre-loads the menu categories.

What I really want to be able to do is something like:

Restaurant = context.Restaurant
.Include(r => r.MenuCategory)
.Include(r => r.MenuCategory.MenuItems)
.FirstOrDefault(r => r.RestaurantId == resaurantId);

But clearly this isn't available as r.MenuCategory is an enumerable

...the work around is to use the standard notation:

context.Restaurant.Include("MenuCategory.MenuItems");

...but this is not strongly typed. This question is about finding a strongly typed answer

This is the current extension method:

public static ObjectQuery<T> Include<T>(this ObjectQuery<T> query, Expression<Func<T, object>> path)
{
    // Retrieve member path:  
    List<PropertyInfo> members = new List<PropertyInfo>();
    EntityFrameworkHelper.CollectRelationalMembers(path, members);

    // Build string path:  
    StringBuilder sb = new StringBuilder();
    string separator = "";
    foreach (MemberInfo member in members)
    {
        sb.Append(separator);
        sb.Append(member.Name);
        separator = ".";
    }

    // Apply Include:  
    return query.Include(sb.ToString());
}

How could this be adapted to allow a strongly typed form of:

context.Restaurant.Include("MenuCategory.MenuItems");

2条回答
该账号已被封号
2楼-- · 2019-07-16 12:06

I have a Tip that allows exactly this: Tip 28 - How to implement an eager load strategy

Uses a nifty trick I think.

Alex

查看更多
Viruses.
3楼-- · 2019-07-16 12:08

A far less elegant but much quicker to implement method might be as follows:

var list = dataContext.CartLists.Include(typeof(CartListItem).Name).Where(l => l.CustNum == customerNumber && l.ListTypeID == (int)ShoppingCartType.WebShoppingCart).Single();

. . . but you'll need to ensure that you haven't had the EF model generator pluralize your entity set names. This is kind of an ugly solution, but it should give you compile errors once you update your EF model if your table names ever change, as ours just did, and you won't have to actually execute your code to try to find places where your strings don't match actual entities.

查看更多
登录 后发表回答