Frage

In a multitenant application that uses composite keys (e.g. SiteId, $(Table)Id) for everything, I have the following two tables:

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

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

and a foreign key from Owner (SiteId, ThingId) to Thing (SiteId, ThingId).

If I write a method like this:

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

I get the exception

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

To fix this, I could add a second copy of SiteId (perhaps ThingSiteId) to the Owner table. But it's only ever going to be equal to the SiteId, so I'd be spending database size and schema complexity to work around my ORM.

How can I tell LINQ to SQL that it doesn't need to worry about that half of the foreign key relationship, and only set Owner.ThingId=NULL?

War es hilfreich?

Lösung

Set ThingId = null instead of Thing = null. Don't reuse your DataContext, otherwise you might get a "Foreign key is already set" exception.


LINQ is actively preventing this from being any easier. In ChangeTracker.SynchDependentData(), every column is checked to see if it is part of any associations, and then an exception is thrown if the column was

  1. set to null

  2. the association has ANY non-nullable columns(!)

This is a bug in LINQ-to-SQL, in my opinion.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top