在使用复合密钥的多租户应用程序中(例如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()
中,检查每一列是否是任何关联的一部分,然后如果该列是则抛出异常
-
设置为空
-
关联具有ANY不可为null的列(!)
在我看来,这是LINQ to SQL中的一个错误