实体框架 - 多对多子查询

时间:2010-05-14 22:50:30

标签: entity-framework many-to-many

之前我问了一个关于此的问题,但我的数据库结构发生了变化,虽然它使其他事情变得更简单,但现在这个部分更复杂了。 Here是上一个问题。

当时,我的EF Context有一个UsersProjects对象,因为还有其他属性。现在我已经简化了那个表,它只是键,所以我的所有EF上下文都知道UsersProjects以及它们之间的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 :(得分:0)

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;

答案 1 :(得分:0)

丹尼尔,我尝试过你所拥有的东西并遇到了一些问题。你能解释一下这些错误是什么意思吗?

我试过了:

        // 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事件探查器中,它都在一个查询中执行,那么为什么它显示上下文已被处理?另外,为什么它不能使用me对象而不是lambda?

        // 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();