Entity Framework 4.0 - возвращение списка объектов модели + количество дочерних объектов на объект - PullRequest
1 голос
/ 13 февраля 2011

Я сталкиваюсь с общей потребностью в моем проекте по возврату коллекций объектов моей модели плюс количество определенных типов дочерних элементов в каждом, но я не знаю, возможно ли это или как смоделировать "TotalCount" "свойство в классе Model и заполнить его как часть одного запроса Entity Framework, предпочтительно используя запросы LINQ. Возможно ли сделать это, хотя можно использовать Entity Framework .Include ("Object") и .Skip () и .Take ()? Я новичок в Entity Framework, поэтому мне может не хватать тонны очевидных вещей, которые могут это позволить ...

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

В такой модели:

Таблица: Класс

Таблица: профессор

Таблица: Посетитель

Таблица: ClassComment

Я хотел бы вернуть список объектов Class в форме List, но я также хотел бы, чтобы количество посетителей и комментариев Class было определено в одном запросе (предпочтительно LINQ) и задано в двух свойствах Class, называемых AttendeeCount и ClassCommentCount.

Пока у меня есть это:

var query = from u in context.Classes
            orderby tl.Name
            select u;

List<Class> topics = ((ObjectQuery<Class>)query)
    .Include("ClassComments")
    .Skip(startRecord).Take(recordsToReturn).ToList();

Любые предложения или альтернативные подходы к запросам, которые все еще позволяют использовать .Include () и разбиение на страницы, будут высоко цениться для того, чтобы, если это вообще возможно, создать один запрос к базе данных. Спасибо за любые предложения!

Ответы [ 2 ]

3 голосов
/ 13 февраля 2011

Попробуйте это:

public class ClassViewModel {
    public Class Class { get; set; }
    public int AttendeeCount { get; set; }
    public int ClassCommentCount { get; set; }
}


var viewModel = context.Classes.Select(clas => 
    new ClassViewModel { 
        Class = clas, 
        AttendeeCount = clas.ClassAttendes.Count, 
        ClassCommentCount = clas.ClassComments.Count}
).OrderBy(model => model.ClassCommentCount).Skip(startRecord).Take(recordsToReturn).ToList();

Вы не должны включать комментарии, чтобы получить счет.

2 голосов
/ 13 февраля 2011

Так работать не будет. Самый простой подход - использовать проекцию на анонимный (или пользовательский) не тип сущности. Я бы попробовал что-то вроде этого:

var query = context.Classes
              .Include("ClassComments")  // Only add this if you want eager loading of all realted comments
              .OrderBy(c => c.Name)
              .Skip(startRecord)
              .Take(recordsToReturn)
              .Select(c => new 
                 {
                   Class = c,
                   AttendeeCount = c.Attendees.Count(),
                   ClassCommentCount = c.ClassComments.Count() // Not needed because you are loading all Class comments so you can call Count on loaded collection
                 });

Проблема в вашем требовании - это свойства AttendeeCount и ClassCommentCount. Вы не можете легко добавить их в свою модель, потому что в базе данных нет соответствующего столбца (если только вы его не определите, и в этом случае вам не нужно вручную считать записи). Вы можете определить их в частичной реализации Class, но в этом случае вы не можете использовать их в запросе Linq-to-entity.

Единственный способ отобразить это в EF - это использовать представление БД и создать специальную сущность только для чтения, чтобы представить ее в вашем приложении, или использовать DefiningQuery , которая представляет собой пользовательскую команду SQL, определенную в SSDL вместо таблицы БД или посмотреть.

...