LINQ to SQL:复合FK只能为半空



在使用复合密钥的多租户应用程序中(例如SiteId, $(Table)Id)对于所有的东西,我有以下两张表:

Owner (
     SiteId bigint NOT NULL,
     OwnerId bigint NOT NULL,
     ThingId bigint NULL
)
Thing (
     SiteId bigint NOT NULL,
     ThingId bigint NOT NULL
)

以及从CCD_ 2到CCD_。

如果我写一个这样的方法:

void RemoveThing(Owner owner)
{
    owner.Thing = null;
    db.SubmitChanges();
}

我得到了异常

System.InvalidOperationException: An attempt was made to remove a relationship between a
Thing and a Owner. However, one of the relationship's foreign keys (Owner.MultiId,
Owner.ThingId) cannot be set to null.
at System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.SynchDependentData()
at System.Data.Linq.ChangeProcessor.ValidateAll(IEnumerable`1 list)
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges()
at proj.Program.RemoveThing() in C:projProgram.cs:line 115

为了解决这个问题,我可以向Owner表中添加SiteId(可能是ThingSiteId)的第二个副本。但它永远不会等于SiteId,所以我会花费数据库大小和模式复杂性来处理我的ORM。

如何告诉LINQ to SQL,它不需要担心那一半的外键关系,只需要设置Owner.ThingId=NULL

设置ThingId = null而不是Thing = null。不要重复使用DataContext,否则可能会出现"外键已设置"异常。


LINQ正在积极防止这种情况变得更容易。在ChangeTracker.SynchDependentData()中,检查每一列是否是任何关联的一部分,然后如果该列是则抛出异常

  1. 设置为空

  2. 关联具有ANY不可为null的列(!)

在我看来,这是LINQ to SQL中的一个错误

最新更新