实体框架无法完成删除
我试图删除Invoice
以及任何相关Costs
。 Invoice
至Costs
是一对多关系。实体框架无法完成删除
我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
。
不幸的是,没有任何建议适用于我的情况。我的工作是使用两个不同的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
标准做法。
您可以将删除发票移至循环之后吗? 例如: -
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);
来完成,这将是添加在你的数据库中删除级联的最好方法。你很可能有一个简单的外键约束。您需要删除该约束并在删除时再次添加级联。
完成此的发言看起来类似以下内容:
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费用也将被删除。
如果模型正确设置,以便它知道你有一个外键约束,相信你真正需要做的是确保EF拥有所有的相关信息删除之前,像这样:
Invoice invoiceToDelete = db.Invoices.Include(i=>i.Costs).First(i => i.Id == id);
db.Invoices.Remove(invoiceToDelete);
db.SaveChanges();
同意,除非我将它保留在实体框架中,因此丢弃的数据库将重建它与级联。看到这个SO:http://*.com/questions/17487577/entity-framework-ef-code-first-cascade-delete-for-one-to-zero-or-one-relations – MutantNinjaCodeMonkey
非常真实,无论哪种方式完成同样的事情。这完全取决于您是否需要与数据库进行所有交互来进行级联。 –
@MutantNinjaCodeMonkey我从现有的数据库实现中首先使用代码。最好的做法是按照SO链接中描述的方式设置级联,或者是Matt的SQL本质上是做同样的事情,也许是更干净的方法? – KidBatman