LINQ到SQL:调用的SubmitChanges时,执行顺序()

问题描述:

我有2个相关的数据库表这在简化的形式看起来像这样

I have 2 related database tables which in simplified form look like this

Product(
  product_id,
  name
)

ProductSpecs(
  spec_id,
  product_id,
  name,
  value
)

外键是通过PRODUCT_ID字段设置和ProductSpecs表对(产品编号,名称)对唯一的约束。

Foreign key is set via product_id field and ProductSpecs table has a unique constraint on (product_id, name) pair.

现在的我,当用户编辑产品规格和保存数据,我删除旧的规范和插入所有的新的ASP.NET MVC应用程序。

Now in my ASP.NET MVC application when user edits product specs and saves the data I delete old specs and insert all as new ones.

我做到这一点,首先调用DataContext.DeleteAllOnSubmit(),并提供电流(旧)ProductSpecs作为参数,然后我添加新的功能到Product.ProductSpecs集合。

I do this by first calling DataContext.DeleteAllOnSubmit() and providing current (old) ProductSpecs as a parameter, and then I add new specs to the Product.ProductSpecs collection.

然后我打电话DataContext.SubmitChanges(),并得到一个错误,我的唯一约束被侵犯。

Then I call DataContext.SubmitChanges() and get an error that my unique constraint was violated.

通过查看由DataContenxt.GetChangeText返回的SQL语句()我可以看到嵌件的DELETE之前执行(尽管我叫DeleteAllOnSubmit()添加前)。

By looking at the SQL statements returned by DataContenxt.GetChangeText() I can see that INSERTs are executed before DELETEs (even though I called DeleteAllOnSubmit() before Add).

什么是这种现象的原因以及如何解决或解决方法呢?

What is the reason of this behavior and how to fix or workaround it?

感谢。

是的,出于某种原因,LINQ to SQL的执行所有删除的最后一件事。而且也没有办法改变这一点。

Yes, for some reason, Linq to SQL perform all deletes as the last thing. And there is no way to change that.

或许有。我没有看过成codeGEN的DataContext,看看我们是否可以覆盖一些东西在那里。

Or maybe there is. I haven't looked into the codegen DataContext to see if we can override something there.

您可以调用的SubmitChanges(),你要尽可能多的时间。我的解决方法,当我需要删除的第一件事情,是记住我删除,调用的SubmitChanges(),然后执行插入和更新,并再次呼吁的SubmitChanges。

You can call SubmitChanges() as many times you want. My workaround when I need to delete as the first thing, is mark my deletions, call SubmitChanges(), then perform inserts and updates, and call SubmitChanges once again.

你可以用一切一个TransactionScope内:

You can wrap everything inside of a TransactionScope:

    var deletables =
        from toDelete in db.NamedValues
        where toDelete.Name == knownValue.Name
        select toDelete;

    using (var scope = new TransactionScope())
    {
        db.NamedValues.DeleteAllOnSubmit(deletables);
        db.SubmitChanges();

        db.NamedValues.InsertOnSubmit(knownValue);
        db.SubmitChanges();

        scope.Complete();
    }