EF6 Select 具有多对多关系
EF6 Select with Many to Many relationship
我是 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 table 在我的上下文文件中的表现方式
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"));
这是Role.cs
public class Role
{
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Role()
{
Users_Roles = new HashSet<Users_Roles>();
Views = new HashSet<View>();
}
public int ID { get; set; }
[Column("Role")]
[Required]
[StringLength(50)]
public string Role1 { get; set; }
public bool IsAdminRole { get; set; }
public int OrderBy { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Users_Roles> Users_Roles { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<View> Views { get; set; }
}
这是View.cs
[Table("View")]
public class View
{
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public View()
{
PermanentRedirects = new HashSet<PermanentRedirect>();
Users_Roles = new HashSet<Users_Roles>();
Versions_View = new HashSet<Versions_View>();
View_Links = new HashSet<View_Links>();
View_Localized = new HashSet<View_Localized>();
View1 = new HashSet<View>();
ViewGroups = new HashSet<ViewGroup>();
ViewGroups1 = new HashSet<ViewGroup>();
languages = new HashSet<language>();
Roles = new HashSet<Role>();
}
[StringLength(32)]
public string ID { get; set; }
public bool HideFromNavigationOverride { get; set; }
[StringLength(32)]
public string ParentID { get; set; }
public int? ThemeID { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PermanentRedirect> PermanentRedirects { get; set; }
public virtual Theme Theme { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Users_Roles> Users_Roles { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Versions_View> Versions_View { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<View_Links> View_Links { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<View_Localized> View_Localized { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<View> View1 { get; set; }
public virtual View View2 { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ViewGroup> ViewGroups { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ViewGroup> ViewGroups1 { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<language> languages { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Role> Roles { get; set; }
}
这是我正在尝试的 LINQ,但由于我不明白如何使用 View_Roles table,所以它确实无法满足我的需要。
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();
在您的情况下,结点 table 未直接映射,它是隐藏的,因此获取所需相关数据的一种解决方案是使用 SelectMany
扩展方法。首先将条件应用于查询的末端之一,在我的示例中是 Versions
,然后应用 SelectMany
,这将在两个 table 之间生成内部连接并展平一个集合中的结果。
更新
我认为问题是因为 Version 和 View
在您的数据库中并没有真正直接相关,所以您将进行显式内部连接:
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();
我是 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 table 在我的上下文文件中的表现方式
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"));
这是Role.cs
public class Role
{
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Role()
{
Users_Roles = new HashSet<Users_Roles>();
Views = new HashSet<View>();
}
public int ID { get; set; }
[Column("Role")]
[Required]
[StringLength(50)]
public string Role1 { get; set; }
public bool IsAdminRole { get; set; }
public int OrderBy { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Users_Roles> Users_Roles { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<View> Views { get; set; }
}
这是View.cs
[Table("View")]
public class View
{
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public View()
{
PermanentRedirects = new HashSet<PermanentRedirect>();
Users_Roles = new HashSet<Users_Roles>();
Versions_View = new HashSet<Versions_View>();
View_Links = new HashSet<View_Links>();
View_Localized = new HashSet<View_Localized>();
View1 = new HashSet<View>();
ViewGroups = new HashSet<ViewGroup>();
ViewGroups1 = new HashSet<ViewGroup>();
languages = new HashSet<language>();
Roles = new HashSet<Role>();
}
[StringLength(32)]
public string ID { get; set; }
public bool HideFromNavigationOverride { get; set; }
[StringLength(32)]
public string ParentID { get; set; }
public int? ThemeID { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PermanentRedirect> PermanentRedirects { get; set; }
public virtual Theme Theme { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Users_Roles> Users_Roles { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Versions_View> Versions_View { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<View_Links> View_Links { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<View_Localized> View_Localized { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<View> View1 { get; set; }
public virtual View View2 { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ViewGroup> ViewGroups { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ViewGroup> ViewGroups1 { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<language> languages { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Role> Roles { get; set; }
}
这是我正在尝试的 LINQ,但由于我不明白如何使用 View_Roles table,所以它确实无法满足我的需要。
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();
在您的情况下,结点 table 未直接映射,它是隐藏的,因此获取所需相关数据的一种解决方案是使用 SelectMany
扩展方法。首先将条件应用于查询的末端之一,在我的示例中是 Versions
,然后应用 SelectMany
,这将在两个 table 之间生成内部连接并展平一个集合中的结果。
更新
我认为问题是因为 Version 和 View
在您的数据库中并没有真正直接相关,所以您将进行显式内部连接:
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();