EntityRefof a LINQ to SQL object in memory. According to MSDN, EntityRef is a structure that:
Provides for deferred loading and relationship maintenance for the singleton side of a one-to-many relationship in a LINQ to SQL application.
In the system we're currently developing, most database records have temporary copies that we refer to as shadow records. A shadow record is a temporary copy of a database record that is used for editing until it is "approved", at which point it gets copied to the real record. Shadow records are identical to the actual record, but with a different primary key. They are stored in the same database table as the real records. Those tables have a foreign key relationship to themselves from a shadow source column to the primary key column.
For example, one table is
Address. In addition to all the columns that represent the address information, there is the
AddressIdcolumn and a
ShadowSourceIdis a foreign key to the
AddressIdin the same table. Rows with a null value for
ShadowSourceIdare approved records, while rows with a value for
ShadowSourceIdare shadow records.
1: Address duplicateAddress = DuplicateAddress(originalAddress);
Then we modify the duplicate to turn it into a shadow record:
1: duplicateAddress.AddressId = Guid.NewGuid();2: duplicateAddress.ShadowSourceId = originalAddress.Id;
In the DBML designer, I named the EntityRef as
ShadowSource, so that writing
duplicateAddress.ShadowSourcewill give you
originalAddress. This is where the tricky behavior comes in. In the lines above, I set the
ShadowSourceIddirectly. At this point, if you try to access the
ShadowSourceEntityRef, you will get a
nullvalue (even though
ShadowSourceIdhas been set). Instead, if I were to create the shadow record as follows:
1: duplicateAddress.AddressId = Guid.NewGuid();2: duplicateAddress.ShadowSource = originalAddress;
ShadowSourceEntityRef will have the expected value. However, now the
ShadowSourceIdproperty will contain a
The reason for this is that the ID property and the EntityRef, even though they reference the same thing, are not "wired up" by LINQ to SQL until you call
SubmitChanges(). Whichever one you set, the other will still be
nulluntil you submit your changes and LINQ to SQL creates all the proper connections. If for some reason you don't want to submit your changes, you will have to set both the ID property and the EntityRef for them to have their proper values:
1: duplicateAddress.AddressId = Guid.NewGuid();2: duplicateAddress.ShadowSource = originalAddress;3: duplicateAddress.ShadowSourceId = originalAddress.Id;
While this seems redundant, sometimes it's necessary. In my situation, I didn't need to submit my changes because this was a unit test for a small piece of the process. If you need both of these to be available, then you'll need to decide which solution is the most appropriate in your situation - submitting your changes or simply setting both manually.