在EntityFramework中配置多对多关系
本文关键字:关系 配置 EntityFramework | 更新日期: 2023-09-27 17:58:35
我正在使用ASP。NET MVC来创建一个示例web应用程序,我想配置多对多关系。我有产品和交易。我想让每笔交易都包括一种或多种产品。我有一个代码优先类定义如下:
public class Product
{
public int ProductID { get; set; }
public string Name { get; set; }
}
public class Transaction
{
public int TransactionID { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
然后,我在ApplicationDbContext
中添加了一些内容,最后它看起来是这样的:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
//protected override void OnModelCreating(DbModelBuilder modelBuilder)
//{
// modelBuilder.Entity<Transaction>().HasMany(x => x.Products).WithMany();
//}
public DbSet<Product> Products { get; set; }
public DbSet<Transaction> Transactions { get; set; }
}
之后,我启用了迁移,并添加了一些要在数据库中显示的测试数据。测试数据如下:
protected override void Seed(MyApp.Models.ApplicationDbContext context)
{
var pr = new List<Product>();
pr.Add(new Product { Name = "Book" });
pr.Add(new Product { Name = "Table" });
pr.Add(new Product { Name = "Chair" });
pr.ForEach(i => context.Products.AddOrUpdate(p => p.Name, i));
context.SaveChanges();
context.Transactions.AddOrUpdate(
t => t.Products,
new Transaction { Products = new List<Product>(pr.Where(p => p.Name == "Book" || p.Name == "Table")) },
new Transaction
{
Products = new List<Product>(pr.Where(p => p.Name == "Chair" || p.Name == "Book" || p.Name == "Table"))
}
);
context.SaveChanges();
}
然后,我创建了一个新的迁移,并更新了数据库。但是,当我检查这些表时,事务表中只有TransactionID
列,而没有包含产品ID的Products
列。相反,在产品表中有一个名为Transaction_TransactionID
的新列,但它持有该产品所属的最新事务的id。因此,这种关系并不完全正确。
可以看出,我还注释了一个方法,我想手动指定多对多关系。但是,当我取消注释并尝试更新数据库时,我会收到一些错误,其中一个错误是:
Identity UserRole::EntityType"IdentityUserRole"未定义键。定义此EntityType 的密钥
有什么想法可以实现我想要的吗?在项目的后期,我需要查询交易,并找到哪些产品涉及哪些交易。
建立多对多关系时,将为其创建第三个表,其中包含两个表的主键。
您应该在上下文类中指定多对多关系,就像您在注释部分中所做的那样。但是,由于ApplicationDbContext
继承自IdentityDbContext
类,您应该调用base.OnModelCreating
,以便也应用base.OnModelCreating
的模型定义。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Transaction>().HasMany(x => x.Products).WithMany();
base.OnModelCreating(modelBuilder);
}