Linq EF6选择多对多关系

Linq EF6选择多对多关系,linq,entity-framework-6,Linq,Entity Framework 6,我是EF的新手,尝试检索需要多对多关系的结果 这是模式 这是我试图用LINQ获得的SQL版本 select v.ID ViewID, ve.Title, ve.VersionID, r.Role, vr.RoleID from [View] v, Roles r, Versions ve, View_Roles vr where v.ID = vr.ViewID and r.ID = vr.RoleID and ve.ContentStatusID = 2 and ve.ViewID = v.

我是EF的新手,尝试检索需要多对多关系的结果

这是模式

这是我试图用LINQ获得的SQL版本

select v.ID ViewID, ve.Title, ve.VersionID, r.Role, vr.RoleID
from [View] v, Roles r, Versions ve, View_Roles vr
where v.ID = vr.ViewID
and r.ID = vr.RoleID
and ve.ContentStatusID = 2
and ve.ViewID = v.ID
order by r.Role
这是上面的结果视图

这就是View_Roles表在我的上下文文件中的显示方式

modelBuilder.Entity<Role>()
                .Property(e => e.Role1)
                .IsUnicode(false);

    modelBuilder.Entity<Role>()
                .HasMany(e => e.Views)
                .WithMany(e => e.Roles)
                .Map(m => m.ToTable("View_Roles").MapLeftKey("RoleID").MapRightKey("ViewID"));

我认为你能实现你正在尝试的目标的一个方法是:

var query= PagesContext.Versions.Where(ve=>ve.ContentStatusID == 2)
                                .SelectMany(ve=>ve.View.Roles
                                                  .Where(r=>r.IsAdminRole == false)
                                                  .Select(r=> new RestrictedPage
                                                                   {
                                                                     ViewID = ve.ViewID,
                                                                     Title = ve.Title,
                                                                     RoleID = r.ID,
                                                                     Role = r.Role1,
                                                                     VersionID = ve.VersionID
                                                                   })).ToList();
在您的情况下,连接表不是直接映射的,而是隐藏的,因此获取所需相关数据的一个解决方案是使用
SelectMany
extension方法。首先将条件应用于查询的to端之一,在我的示例中是
Versions
,然后应用
SelectMany
,这将在两个表之间生成一个内部联接,并在一个集合中展平结果

更新 我认为问题是因为版本和视图在数据库中并不直接相关,所以要进行显式的内部连接:

var query= PagesContext.Versions.Where(ve=>ve.ContentStatusID == 2)
                                .Join( PagesContext.Views, ve=>ve.ViewId, v=>v.ID,(ve,v)=>v)
                                .SelectMany(v=>v.Roles
                                                  .Where(r=>r.IsAdminRole == false)
                                                  .Select(r=> new RestrictedPage
                                                                   {
                                                                     ViewID = ve.ViewID,
                                                                     Title = ve.Title,
                                                                     RoleID = r.ID,
                                                                     Role = r.Role1,
                                                                     VersionID = ve.VersionID
                                                                   })).ToList();

你能更详细地解释一下你期望的结果是什么,为什么你说没有得到你所需要的。您显示的sql查询正在多个表之间进行交叉联接linq查询的结果不包括对View_Roles表的引用,因此我无法筛选我要查找的结果。在本例中,“.SelectMany(ve=>ve.Roles”,ve.Roles告诉我“Version”不包含的定义,并且找不到接受“Version”类型的第一个参数的可访问扩展方法(是否缺少using指令或程序集引用?)但是根据您的配置,您在
视图中有一个
角色的集合
实体:
。有很多(e=>e.Roles)
,对吗?有两个引用,我忽略了添加它们。modelBuilder.entity().Property(e=>e.Role1)。IsUnicode(false);modelBuilder.entity().HasMany(e=>e.Views)。WithMany(e=>e.Roles)。Map(m=>m.ToTable(“View_角色”)。MapLeftKey(“RoleID”)。MapRightKey(“ViewID”));首先,您需要知道有两种语法:查询语法和方法语法。我同时使用这两种语法,因为您将更容易学习查询语法,因为它更接近sql。关于参考资料,对我来说,这是最好的语法之一:关于如何使用方法的示例:
return (
                from v in PagesContext.Versions 
                from r in PagesContext.Roles
                where v.ContentStatusID == 2 && r.IsAdminRole == false
                select new RestrictedPage
                {
                    ViewID = v.ViewID,
                    Title = v.Title,
                    RoleID = r.ID,
                    Role = r.Role1,
                    VersionID = v.VersionID
                }
           ).ToList();
var query= PagesContext.Versions.Where(ve=>ve.ContentStatusID == 2)
                                .SelectMany(ve=>ve.View.Roles
                                                  .Where(r=>r.IsAdminRole == false)
                                                  .Select(r=> new RestrictedPage
                                                                   {
                                                                     ViewID = ve.ViewID,
                                                                     Title = ve.Title,
                                                                     RoleID = r.ID,
                                                                     Role = r.Role1,
                                                                     VersionID = ve.VersionID
                                                                   })).ToList();
var query= PagesContext.Versions.Where(ve=>ve.ContentStatusID == 2)
                                .Join( PagesContext.Views, ve=>ve.ViewId, v=>v.ID,(ve,v)=>v)
                                .SelectMany(v=>v.Roles
                                                  .Where(r=>r.IsAdminRole == false)
                                                  .Select(r=> new RestrictedPage
                                                                   {
                                                                     ViewID = ve.ViewID,
                                                                     Title = ve.Title,
                                                                     RoleID = r.ID,
                                                                     Role = r.Role1,
                                                                     VersionID = ve.VersionID
                                                                   })).ToList();