![](/img/trans.png)
[英]Query a many-to-many relationship with linq/Entity Framework. CodeFirst
[英]How to run linq query on many-to-many relationship in c# with entity framework
我在查詢Linq To Entities中的多對多關系時遇到問題。 我基本上是想使用Linq復制此查詢:
SELECT
Users.UserName, Roles.RoleName, Users.IsActive
FROM
Users
LEFT JOIN
UserRoles ON Users.UserID = UserRoles.UserID
LEFT JOIN
Roles ON UserRoles.RoleID = Roles.RoleID
我在Linqpad中嘗試了此查詢,它的工作原理絕對不錯
Users.Join(UserRoles, u=>u.UserId, r=>r.UserId, (u,r) => new { u, r})
.Join(Roles, ur=>ur.r.RoleId, q=>q.RoleId, (ur,q)=>new {ur, q})
.Select(m=> new {m.ur.u.UserName, m.ur.u.IsActive, m.q.RoleName})
但是,當我在C#應用程序中嘗試相同的查詢時,它將引發錯誤
錯誤
“上下文”不包含“ UserRoles”的定義,找不到可以接受類型為“ Context”的第一個參數的擴展方法“ UserRoles”(是否缺少using指令或程序集引用?)
我的問題是如何在C#
創建LINQ查詢以檢索分配給Roles
Users
?
我的DbContext包含
public class Context : DbContext
{
public Context()
: base("Name=xyz")
{
if (!Database.Exists("xyz"))
Database.SetInitializer(new Initializer());
}
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new UserMap());
base.OnModelCreating(modelBuilder);
}
}
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
HasMany(r => r.Roles).WithMany(u=>u.Users)
.Map(m =>
{
m.ToTable("UserRoles");
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
});
}
}
public class User
{
public User()
{
this.Roles = new HashSet<Role>();
}
public int UserId { get; set; }
public string UserName { get; set; }
public string PasswordHash { get; set; }
public DateTime? LastLoggedOn { get; set; }
public DateTime? PasswordChangedOn { get; set; }
public int IsActive { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
public class Role
{
public Role()
{
this.Users = new HashSet<User>();
}
public int RoleId { get; set; }
public string RoleName { get; set; }
public string Description { get; set; }
public virtual ICollection<User> Users { get; set; }
}
編輯:查看問題中的代碼:沒有定義UserRoles
。 您需要根據EF來了解多對多關系,從而進行重構:
var res = db.Users.SelectMany(u =>
u.Roles.Select(r =>
new {
u.UserName,
r.RoleName,
u.IsActive
}
)
);
EF理解(因為已經定義了)如何進行聯接:代表關系的Roles
集合將僅根據屬於您的用戶的角色進行過濾。
原始答案
編寫查詢的方法的定義是哪種類型?
LINQpad(IIRC)像運行DbContext
派生類型的方法一樣運行所有內容。 因此, DbSet<T>
屬性映射表無需限定即可使用(在您的情況下為UserRoles
)。 如果您不是上下文類型的成員,則需要使用上下文的實例來限定實體集:
using (var db = new MyContext()) {
var data = db.Users.Join(db.UserRoles, u=>u.UserId, r=>r.UserId, (u,r) => new { u, r})
.Join(db.Roles, ur=>ur.r.RoleId, q=>q.RoleId, (ur,q)=>new {ur, q})
.Select(m=> new {m.ur.u.UserName, m.ur.u.IsActive, m.q.RoleName})
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.