我正在尝试删除Invoice
以及任何相关的Costs
。 Invoice
到Costs
是一对多关系。
My Snipp:
Invoice invoiceToDelete = db.Invoices.First(i => i.Id == id);
db.Invoices.Remove(invoiceToDelete);
var costs = db.Costs.Where(i => i.InvoiceId == id);
foreach (var cost in costs)
{
//Delete all related costs.
db.Costs.Remove(cost);
}
//Tried using this as well to try and delete all related costs
//db.Costs.RemoveRange(db.Costs.Where(x => x.InvoiceId == id));
db.SaveChanges();
如果Invoice
没有相关的Costs
,则代码执行正常,Invoice
将从表中删除。
但是当Invoice
与Costs
相关时,会引发以下错误:
The DELETE statement conflicted with the REFERENCE constraint "FK_Costs_Invoices". The conflict occurred in database "MyDB", table "dbo.Costs", column 'InvoiceId'.
The statement has been terminated.
在SSMS中编写删除SQL语句,我可以根据Costs
的外键从InvoiceId
表中删除。
答案 0 :(得分:1)
完成此操作的最佳方法是在数据库中添加级联删除。您很可能有一个简单的外键约束。您将需要删除该约束并在删除时使用级联再次添加它。
完成此操作的语句如下所示:
ALTER TABLE dbo.Costs
DROP CONSTRAINT FK_Invoices_Costs --name of constraint
ALTER TABLE dbo.Costs
ADD CONSTRAINT FK_Invoices_Costs_Cascade
FOREIGN KEY (InvoiceId) REFERENCES dbo.Invoices(InvoiceId) ON DELETE CASCADE
完成此设置后;使用EF删除的发票的InvoiceId的所有费用也将被删除。
答案 1 :(得分:0)
您可以将删除发票移动到循环后吗? e.g:
var costs = db.Costs.Where(i => i.InvoiceId == id);
foreach (var cost in costs)
{
//Delete all related costs.
db.Costs.Remove(cost);
}
db.Invoices.Remove(invoiceToDelete);
答案 2 :(得分:0)
如果您的模型设置正确,以便它知道您有外键约束,我相信您真正需要做的就是确保EF在删除之前拥有所有相关信息,如下所示:
Invoice invoiceToDelete = db.Invoices.Include(i=>i.Costs).First(i => i.Id == id);
db.Invoices.Remove(invoiceToDelete);
db.SaveChanges();
答案 3 :(得分:-1)
不幸的是,这些建议都没有适用于我的情况。我的工作是使用两个不同的DbContext
实例进行更改,以对Invoices
和{}进行更改。分别为Costs
。
using (var ctx = new MyDbContext())
{
//Delete Invoice
ctx.SaveChanges();
}
using (var ctx = new MyDbContext())
{
//Delete related costs
ctx.SaveChanges();
}
非常感谢Matt Rowland。他的答案可能是更合适的解决方案,但不幸的是,无论出于何种原因,我无法为我的特定实例工作。我正在处理的sln
最初是由顾问开发的,他们可能没有遵守EF
标准做法。