Entity Framework - подзапрос «многие ко многим» - PullRequest
0 голосов
/ 15 мая 2010

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

В то время у моего EF Context был объект UsersProjects, потому что были другие свойства. Теперь, когда я упростил эту таблицу, это всего лишь ключи, поэтому все, что знает мой EF-контекст, это Users и Projects и отношения M2M между ними. EF больше не знает UsersProjects.

Поэтому моя цель - сказать «покажи мне всех пользователей, которые работают со мной над проектами».

в SQL это будет выглядеть примерно так:

SELECT * FROM Users INNER JOIN UsersProjects ON Users.ID=UsersProjects.UserID
WHERE ProjectID IN (SELECT ProjectID FROM UsersProjects WHERE UserID=@UserID)

и я начал в EF что-то вроде этого:

            var myProjects =
                (from p in edmx.Projects
                 where p.Users.Contains(edmx.Users.FirstOrDefault(u => u.Email == UserEmail))
                 orderby p.Name
                 select p).ToList();

            var associatedUsers =
                (from u in edmx.Users
                 where myProjects.Contains(?????????)
                 //where myProjects.Any(????????)
                 select u);

Хитрость в том, чтобы найти, что положить в ???????? Кто-нибудь здесь поможет?

Ответы [ 2 ]

0 голосов
/ 16 мая 2010

Даниэль, я попробовал то, что у тебя было, и столкнулся с некоторыми проблемами. Можете ли вы объяснить, что означают эти ошибки?

Я пытался:

        // Doesn't work.
        using (var edmx = new MayflyEntities())
        {
            var me = edmx.Users.First(user => user.Email == UserEmail);
            var myProjects = edmx.Projects.Where(project => project.Users.Contains(me));
            var associatedUsers = myProjects.SelectMany(project => project.Users).Distinct();
        }

, но получил два следующих исключения:

Unable to create a constant value of type 'DomainModel.User'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.

и

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

Итак, я переместил некоторые вещи, и это прекрасно работает, но теперь мне интересно, почему? В SQL Profiler все это выполняется в одном запросе, так почему же он показывает, что контекст был удален? Кроме того, почему он не может использовать объект me вместо лямбды?

        // Works fine
        var edmx = new MayflyEntities();
        var myProjects = edmx.Projects.Where(project => project.Users.Contains(edmx.Users.First(user => user.Email == UserEmail)));
        var associatedUsers = myProjects.SelectMany(project => project.Users).Distinct();
0 голосов
/ 15 мая 2010
var me = context
    .Users
    .First(user => user.Email = "me@example.com");

// Note that there is no call to ToList() or AsEnumerable().
var myProjects = context
    .Projects
    .Where(project => project.Users.Contains(me));

var associatedUsers = context
    .Users
    .Where(user => myProjects.Any(project => user.Project.Contains(project)));

Но есть несколько других возможных решений. Например

var associatedUsers = myProjects
    .SelectMany(project => project.Users)
    .Distinct();

, который я бы предпочел.

Также обратите внимание, что гораздо проще получить myProjects, используя свойство навигации, чем Contains().

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