Entity Framework включает в себя против где - PullRequest
2 голосов
/ 12 октября 2011

Моя структура базы данных такова: OptiUser принадлежит нескольким UserGroup s через таблицу IdentityMap, которая является таблицей соответствия (многие ко многим) с некоторыми дополнительными свойствами, прикрепленными к ней.Каждый UserGroup имеет несколько OptiDashboard с.

У меня есть строка GUID, которая идентифицирует конкретного пользователя (wlid в этом коде).Я хочу получить IEnumerable всех OptiDashboards для пользователя, обозначенного wlid.

Какой из этих двух запросов Linq-to-Entities является наиболее эффективным?Они одинаково работают на бэкэнде?

Кроме того, могу ли я сократить Include операторы варианта 2 до .Include("IdentityMaps.UserGroup.OptiDashboards")?

using (OptiEntities db = new OptiEntities())
{
    // option 1
    IEnumerable<OptiDashboard> dashboards = db.OptiDashboards
        .Where(d => d.UserGroups
            .Any(u => u.IdentityMaps
                .Any(i => i.OptiUser.WinLiveIDToken == wlid)));

    // option 2
    OptiUser user = db.OptiUsers
        .Include("IdentityMaps")
        .Include("IdentityMaps.UserGroup")
        .Include("IdentityMaps.UserGroup.OptiDashboards")
        .Where(r => r.WinLiveIDToken == wlid).FirstOrDefault();

    // then I would get the dashboards through user.IdentityMaps.UserGroup.OptiDashboards
    // (through foreach loops...)
}

Ответы [ 3 ]

4 голосов
/ 12 октября 2011

Возможно, вы неправильно понимаете, что на самом деле делает функция Include.Вариант 1 является чисто синтаксисом запроса, который не влияет на то, что возвращается структурой сущностей.Вариант 2 с функцией Include инструктирует платформу сущностей на нетерпеливое извлечение связанных строк из базы данных при возврате результатов запроса.

Так, вариант 1 приведет к некоторым объединениям, но часть запроса "select" будет ограничена таблицей OptiDashboards.

Опция 2 также приведет к объединениям, но в этом случае она будет возвращать результаты из all включенные таблицы, которые, очевидно, приведут к большему снижению производительности.Но в то же время в результаты будут включены все необходимые вам связанные сущности, избегая [возможной] необходимости в дополнительных обращениях к базе данных.

0 голосов
/ 12 октября 2011

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

var dashboards =
    from u in db.OptiUsers where u.WinLiveIDToken == wlid
    from im in u.IdentityMaps
    from d in im.UserGroup.OptiDashboards
    select d;

Я бы ожидал, что описанное выше будет работать аналогично первому варианту, но вы можете (или не можете) предпочитатьвышеуказанная форма.

0 голосов
/ 12 октября 2011

Я думаю, Include будет отображаться как joins, и вы сможете получить доступ к данным из этих таблиц в своем пользовательском объекте (Eager Загрузка свойств).

Запрос Any будетотображать как exists и не загружать пользовательский объект информацией из других таблиц.

Для лучшей производительности, если вам не нужна дополнительная информация, используйте запрос Any

...