[英]Can't save the same record twice in the join table Entity Framework
我有 2 个表, Invoice
和Product
,我正在使用 EF 将数据保存到我的数据库
这两个类和我的上下文 class 如下:
public class Invoice
{
public int Id { get; set; }
public string InvoiceNumber { get; set; }
public double TotalPrice { get; set; }
public List<Product> Products { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public List<Invoice> Invoices { get; set; }
}
public class DB : DbContext
{
public DB() : base("MyConnectionstringName") { }
public DbSet<Invoice> Invoices { get; set; }
public DbSet<Product> Products { get; set; }
}
最后,这是我将数据保存到数据库的方式:
public string Create(Invoice invoice, List<Product> products)
{
foreach (var item in products)
{
invoice.Products.Add
(db.Products.Find(item.id));
}
db.Invoices.Add(invoice);
db.SaveChanges();
...
return "Invoice was successfully saved";
}
问题是,如果我在products
中有两次相同的 Product ,我只会被添加到数据库中的连接表中一次。 例如,如果客户购买了两个 ID 为 5 的Pepperoni pizza
,保存后, InvoiceProduct
中将只有一行数据指向该特定发票,并且 ProductId 为 5。
一切都很好,直到db.Invoices.Add(invoice);
,因为当我在调试模式下检查invoice
时,我可以看到几个相同的项目被添加到它的Products
属性中,但是当它被保存到数据库时,它只被保存一次。
它适用于同一张发票的几种不同产品。
我在这里没有看到什么?
在 sql 关系世界中,您有 Products 表、Invoice 表和代表多对多关系的 ProductsInvoices 表。 在该表中,您有产品 ID 和发票 ID 的参考。 当你添加它两次时,EF 明白你已经拥有了你想要的关系并且什么都不做。
为了解决这个问题,我将创建另一个名为 InvoiceItem 的 class,它有一个产品、一个发票和一个数量:
public class Invoice
{
public int Id { get; set; }
public string InvoiceNumber { get; set; }
public double TotalPrice { get; set; }
public List<InvoiceItem> Items { get; set; }
}
public class InvoiceItem
{
public int Id { get; set; }
public int Quantity { get; set; }
public Product Product { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public List<InvoiceItem> Invoices { get; set; }
}
public class DB : DbContext
{
public DB() : base("MyConnectionstringName") { }
public DbSet<Invoice> Invoices { get; set; }
public DbSet<InvoiceItem> InvoiceItems { get; set; }
public DbSet<Product> Products { get; set; }
}
建议您还在 InvoiceItem object 中添加产品的项目描述和价格的副本,因为如果将来用户更改产品的价格或名称,它不会更改在过去的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.