Entity Framework - Включить в подзапрос? - Часть 2 - PullRequest
2 голосов
/ 03 ноября 2009

Я не уверен, что это правильно, я уверен, что кто-то скажет мне, если это не так.

Я задал вопрос ( Entity Framework - Включить в подзапрос? ) ранее этим вечером, на который был получен очень хороший ответ и который решил мою проблему. Но, я думаю, что мог бы быть лучший способ, поэтому я собираюсь повторно задать вопрос, но немного по-другому.

Допустим, у меня есть 3 таблицы:

Ресторан 1 ..... M MenuКатегория 1 ..... M MenuItem У меня есть запрос L2E, который выглядит примерно так:

Ресторан = context.Restaurant .Include (r => r.MenuCategory) .FirstOrDefault (r => r.RestaurantId == resaurantId); Который работает в некоторой степени, но он только предварительно загружает категории меню.

То, что я действительно хочу сделать, это что-то вроде:

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

Но очевидно, что это недоступно, так как r.MenuCategory является перечисляемым

... Обходной путь - использовать стандартную запись:

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

... но это не сильно напечатано. Этот вопрос касается поиска строго типизированного ответа

Это текущий метод расширения:

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());
}

Как это можно адаптировать, чтобы разрешить строго типизированную форму:

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

Ответы [ 2 ]

4 голосов
/ 03 ноября 2009

У меня есть Совет, который позволяет именно это: Совет 28 - Как реализовать стратегию активной нагрузки

Использует изящный трюк, я думаю.

Alex

1 голос
/ 23 июля 2010

Гораздо менее элегантный, но гораздо более быстрый способ реализации может быть следующим:

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

. , , но вам нужно убедиться, что у вас не было генератора моделей EF, который умножил бы имена ваших наборов сущностей. Это довольно уродливое решение, но оно должно давать вам ошибки компиляции, как только вы обновите свою модель EF, если имена ваших таблиц когда-либо изменятся, как у нас, и вам не придется фактически выполнять свой код, чтобы попытаться найти места, ваши строки не соответствуют реальным объектам.

...