如何在LINQ to SQL / SQLMetal中有效地更新外键?

时间:2010-09-03 15:03:34

标签: c# linq performance linq-to-sql sqlmetal

我遇到了一个试图更新外键字段的问题:

record.ForeignId = newId;

由于SQLMetal代码抛出System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException()而导致“由于对象的当前状态而导致操作无效”。

我不是第一个遇到这个问题的人:

LinqToSQL Error : Operation is not valid due to the current state of the objecthttp://social.msdn.microsoft.com/forums/en-US/linqtosql/thread/f9c4a01a-195a-4f2b-a1cb-e2fa06e28b25/讨论了这个问题。

他们的解决方案是:

record.Foreign = Database.Foreigns.Single(c => c.Id == newId);

那当然会导致在外部进行数据库查找只是为了得到一个具有我已经知道的Id的对象!那么,如何在没有无意义查询的情况下完成此更新(或者如果我有很多这些FK,则查询)?

3 个答案:

答案 0 :(得分:3)

您可以将父项的实例(具有正确的Id),Attach新建到datacontext作为现有记录状态,然后分配子对象的Parent属性。

以下是一些代码:

int theId = 5;
Parent p = new Parent() { Id = theId};
dc.Parents.Attach(p);
child.Parent = p;

答案 1 :(得分:1)

它没有解决问题,但部分解决额外负载的一种方法是检查现有值是否与新值不同。如果不同,您将产生查询。像 -

这样的东西
if(obj.PropertyID != newValue){
  obj.Property = PropertyClass.Load(newValue)
}

答案 2 :(得分:0)

我有同样的问题。我创建了一个快速的解决方案,可能不是最好的解决方案(因为它可能影响性能),但它对我有用。

在我的解决方案中,我有一个类,我的DataContext在类级别声明,所以我可以在整个过程中使用它。

在我的解决方案中,我想要做的(与您类似)将帐户类型ID更改为用户的其他帐户类型ID(在数据库中为FK)。

由于DataContext已经加载,因此不允许更改。工作?

我创建了一个函数,我在其中创建了一个新的DataContext实例,运行我的LINQ查询,提交更改,然后处理DataContext。