2

在对所有内容都使用复合键(例如SiteId, $(Table)Id)的多租户应用程序中,我有以下两个表:

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

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

Owner (SiteId, ThingId)和一个从to的外键Thing (SiteId, ThingId)

如果我写这样的方法:

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:\proj\Program.cs:line 115

SiteId为了解决这个问题,我可以在表中添加(perhaps ThingSiteId)的第二个副本Owner。但它只会等于 SiteId,所以我会花费数据库大小和架构复杂性来解决我的 ORM。

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

4

1 回答 1

3

设置ThingId = null而不是Thing = null. 不要重复使用您的DataContext,否则您可能会收到“外键已设置”异常。


LINQ 正在积极阻止这变得更容易。在ChangeTracker.SynchDependentData()中,检查每一列以查看它是否属于任何关联,然后如果该列是

  1. 设置为空

  2. 该关联有任何不可为空的列(!)

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

于 2013-07-31T17:38:07.547 回答