2013-09-15 4 views
0

У меня есть запрос с большим количеством включений, и мне интересно, могу ли я сделать Принимает некоторые из включений.Linq Take on Include?

Например, вот один из моих запросов, с (незаконным) Сделайте иллюстрацию того, что я хочу сделать.

var primaryLocation = context.Locations 
       .Include("PhoneNumbers") 
       .Include("Invoices").Take(50) 
       .Include("Invoices.Items") 
       .Include("Schedules") 
       .Include("Staffs") 
       .SingleOrDefault(d => d.Id == locationId); 

В настоящее время единственный способ, которым я могу думать, чтобы сделать это будет выглядеть примерно так:

var primaryLocation = context.Locations 
       .Include("Invoices") 
       .Include("Etc") 
       .SingleOrDefault(d => d.Id == locationId); 

primaryLocation.Invoices = primaryLocation.Invoices.Take(50).ToList(); 

Я предпочел бы не делать это таким образом, так как средство отходили весь список счета-фактуры из базы данных , что мне не нужно.

Есть ли удобный способ построить Take в мой запрос?

+0

Что вы используете для перевода linq на свой сервер? linq2sql, инфраструктура сущности или что-то еще? –

+0

Какой SQL он генерирует для второй части? –

+0

Entity Framework –

ответ

0

Кажется, что у вас есть два противоречивых критерия для того, что вы делаете. Я угадываю здесь, но ты не оставил нас так много, чтобы продолжать.

Поскольку ваш оператор primaryLocation.Invoices = primaryLocation.Invoices.Take(50).ToList(); использует только 1 из ваших включений, я предполагаю, что вы делаете больше вещей с вашим primaryLocation, чем то, что вы нам показали. Это заставляет меня поверить, что вы хотите, чтобы primaryRocation включал весь материал. И тогда вы, кажется, не хотите больше, чем те 50, так что это не все из того, что происходит потом ... Для меня это противоречие. Если вам все требуется, вы должны включить все это.

Если вы хотите, чтобы ваш 50 счетов-фактур специально вы могли получить их отдельно в своем собственном запросе. Я сам использую NHibernate, поэтому я не уверен в синтаксисе будущей структуры Entity, но если вы хотите попросить несколько вещей только с одним обращением к серверу, в NHibernate вы можете сделать серию запросов на фьючерсы разрешить это. Я ожидаю, что структура Entity имеет нечто подобное.

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

+0

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

+0

Это моя точка зрения. Вам нужно решить. Вы все тянете или нет? Если нет, вам нужно разделить свой запрос на более мелкие более конкретные запросы. – Mithon

+0

Итак, ответ на мой вопрос - нет, нет способа построить эти фильтры в одном исходном запросе –

0

Использование проекции вместо того, чтобы слепо вызова Include, если вы не хотите все:

var primaryLocation = context.Locations 
    .Select(location => new { 
     Id = location.Id, 
     Name = location.Name, 
     // ... other properties needed on the front end 
     RecentInvoices = location.Invoices 
      // really should sort if you're only taking 50 
      .OrderByDescending(invoice => invoice.CreatedAt) 
      .Take(50), 
     AllPhoneNumbers = location.PhoneNumbers, 
    }) 
    .SingleOrDefault(location => location.Id == locationId); 

Вы можете использовать проекцию, чтобы получить только информацию счета вам нужно тоже, я просто не хотел чрезмерно усложнять пример.

Используя этот метод, вы получаете именно нужные данные, не добавляя путаницы. Он также позволяет вам называть ваши свойства (например, RecentInvoices выше), чтобы добавить больше смысла.