没有相关记录时删除FK(linq-to-sql)

时间:2010-02-08 09:56:19

标签: c# sql-server linq-to-sql

问题

我有两个相关的表,外键不强制执行FK约束。应允许“子”表指定“父”键,该键为NULL或不存在的ID。

我的数据访问是使用Linq2Sql构建的,它在我的表模型中生成一对多的关系。

问题出现在一些清理代码中,它会每天查看最后一天的所有更改并修复数据中的任何“错误”。

实施例

foreach (var user in data.Users)
{
    // Check if the user has a specified office, which does not exists.
    if (user.OfficeId != null && user.Office == null)
    {
        user.OfficeId = null; // This throws exception
    }
}

异常:System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException:由于对象的当前状态,操作无效

这是正常的行为,有点预期,所以我尝试设置引用对象。但是如何定义一个“空”的Office?

var emptyOffice = new Office();
user.Office = emptyOffice;

上面的代码在用户实例上将OfficeId设置为NULL,但显然它在更新期间失败,因为它尝试将新的“空”Office添加到数据库中。

可能的解决方案

我剩下的就是运行我自己的SQL进行更新,虽然通过Linq2Sql实际上可以做到这一点会很好,因为在相同的行上有其他列我正在更新相关的“父母“不存在。

备注

这里有一些要求对任何评论都很重要:

  • 无法更改数据库。
  • 多个系统依赖于相同的数据库架构。
  • 如果支持这种情况,可能会更改为实体框架。
  • 运行自定义SQL不是问题,我会这样做,直到找到更好的解决方案。
  • 想要在没有任何特殊代码的情况下学习并知道如何做到这一点。

1 个答案:

答案 0 :(得分:1)

我的代码强制执行FK,所以我没有对此进行测试,但您是否尝试过明确设置

user.Office = null;

这也应该强制FK值OfficeId为空。

如果这不起作用,那么下面肯定应该:

user.Office = new Office(); // or keep a cached dummy Office object to save time
user.Office = null;

这将强制FK引用意识到它的值已被更改并设置为null。