Как эффективно загружать вложенные объекты Entity Framework - PullRequest
0 голосов
/ 01 сентября 2011

Я пытаюсь загрузить дерево глубиной 3 в элемент управления древовидной структуры, используя структуру сущностей

Категории, подкатегории и продукты в коде ниже категорий - это IQueryable<ProductCategory>, где ProductCategory - это сгенерированный EF4.0object (генерация кода по умолчанию)

SubCategories - это FK назад к таблице категорий (поэтому теоретически мы могли бы перейти на любую глубину, но область данных будет иметь только два уровня)

var container = categories.Where(c=>c.somecondition).Include("Subcategories.Products");
foreach (var cat in container) {
  addtoTree(cat);
  foreach (var sub in cat.SubCategories)
  {
     addtoTree(sub);
     foreach (var prod in sub.Products) addtoTree(prod);

  }
}

Это все еще выдаёт запросы для каждой итерации внутреннего цикла.Я что-то упустил в конфигурации EF (изменения в контексте?), Чтобы остановить это?Или есть другой способ написания такого рода кода?

(На данный момент, как ужасный хак, я создал представление SQL, которое выравнивает информацию, и я повторяю это, чтобы перестроить вложенные объекты,рука ... противная, но быстрая!)

Ответы [ 2 ]

2 голосов
/ 01 сентября 2011

Попробуйте быстро выполнить запрос перед циклом, вызвав .ToList() в конце:

var container = categories
    .Where(c => c.somecondition)
    .Include("Subcategories.Products")
    .ToList();
0 голосов
/ 06 июня 2017

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

Например, если вы хотите загрузить «базовые» сведения о категориях, подкатегориях и продуктах, подходящих для отображения в древовидной структуре:

var results = dbContext.Categories.Where(c=> /*some condition*/)
    .Select(c=> new {c.CategoryId, c.Name, SubCategories = 
        c.SubCategories.Select(sc=> new { sc.SubCategoryId, sc.Name, Products = sc.Products.Select(p=> new {p.ProductId, p.Name}) }) }).ToList();

Конечно, это может выглядеть не очень красиво, но никаких волшебных строк для выражений энергичной загрузки, и генерируемый EF SQL, как правило, будет на несколько порядков эффективнее и использует индексы, которые вы обычно хотите использовать для этих таблиц.

Для простых сущностей вы можете использовать это, чтобы .Выбирать дочернюю иерархию, но при работе с более тяжелыми сущностями, где вы просто хотите получить несколько ключевых деталей, это может сэкономить немало времени на обработку и пропускную способность сети, только получая и передавая данные, которые вам нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...