Entity Framework 4.1 - TPT Eager Loading - “The Re

2020-07-22 18:28发布

问题:

I have a model with TPT inheritance.

  • Location (abstract)
  • Street (derived from Location)
  • GoogleStreetView (1 Street -> 0..1 GoogleStreetView)

Each of the above has it's own table.

All was working fine until i added the "GoogleStreetView" table (which is backed by a PK/FK to Street).

When i try and do this:

var street = _locationRepository
   .Find()
   .OfType<Street>()
   .Include(x => x.GoogleStreetView)
   .SingleOrDefault(x => x.LocationId == 1);

I get the error:

The ResultType of the specified expression is not compatible with the required type. The expression ResultType is 'Transient.reference[xxxx.Repositories.SqlServer.Location]' but the required type is 'Transient.reference[xxxx.Repositories.SqlServer.Street]'. Parameter name: arguments[0]

What the...?

Then i found this thread which basically states this is a bug with EF 4 (and EF 4.1 RTM, by the looks of it).

I don't understand the workaround of "use an independant association, without a backing FK".

I use the Repository / UoW pattern, so my LocationRepository only has access to ObjectSet<Location>. So i can't do explicit joins in LINQ queries.

At this stage, it's looking like i'll have to not map this table at all, and go fetch it from the database using a stored procedure. Sigh.

Can anyone shed some light on this, and offer a solution?

回答1:

Okay, i've found one workaround.

And that is to flip the FK around.

So instead of:

1 Street -> 0..1 GoogleStreetView

Which is correct, i now have:

* Street -> **0..1 GoogleStreetView

So now Street has a nullable FK pointing to GoogleStreetView.

And that works and acts fine from a code perspective, but from a database perspective this is totally wrong, as with this lack of referential integrity, one particular GoogleStreetView record could point to multiple Street records, which doesn't make any sense.

But this looks like the only proper workaround.

It just seems like EF does not support 1 - 0..1 associations backed by a PK/FK combo.

Unacceptable if you ask me. If they knew this was a bug in EF 4.0, why didn't they fix it in 4.1???

EDIT

Also the above workaround will work, not happy with breaking the referential integrity in the conceptual side.

So i've decided to not map this entity at all and go fetch it from the DB via a stored procedure.