简体   繁体   中英

How do I instruct Entity Framework to select the correct relationship between two tables with multiple foreign keys between them?

I have an entity framework setup which has been generated using the database first approach. In it I have a User table and a profile table.

User
- UserId
- ProfileId

Profile
- ProfileId
- {unimportant profile details}
- ModifiedOn
- CreatedOn

In each of these tables the Ids are their primary keys. The issue is that there are 3 Foreign Key relationships between the two tables.

  1. A User Has A Profile (User.FK_User_Profile User.ProfileId == Profile.ProfileId)
  2. A Profile was Created by a User (Profile.FK_UserCreatedBy Profile.CreatedBy == User.UserId)
  3. A Profile was Modified by a User (Profile.FK_UserModifiedBy Profile.ModifiedBy == User.UserId)

This all works fine in the database. Unfortunately, when I try to access the edmx generated from this with the following Linq query:

databaseContext.User.Where(u => u.UserID == SOMEGUID)
            .Select(p => p.Profile.FirstOrDefault())

the generated sql is this:

SELECT projected details
  FROM ( SELECT
    [Extent1].UserId as UserId,
    [Extent2].ProfileId as ProfileId,
    [Other fields],
    FROM  [dbo].[User] AS [Extent1]
    LEFT OUTER JOIN [dbo].[Profile] AS [Extent2] ON *[Extent1].[UserID] = [Extent2].[ModifiedBy]*
    WHERE [Extent1].[ProfileID] = efGeneratedId
  )  AS [Project1]

The problem is that Left Outer Join criteria. Instead of joining on

Extent1.UserId = Extent2.UserId

it's joining on

Extent1.UserId = Extent2.ModifiedBy

This results in the Linq retrieving all users which modified the profile, rather than the profile that the user has.

How do I instruct EF to map this query, or more likely these relationships, correctly?

As you didn't include any info about edmx generated, I will try to guess..: The model for those tables should produce something like this on User class:

int ProfileId {get; set;}
Profile Profile {get; set;} //->An user has A profile
ICollection<Profile> ProfileX {get; set;} //CreatedBy
ICollection<Profile> ProfileY {get; set;} //ModifiedBy

According to the Sql you posted, the "Profile.FirstOrDefault" of your linq is the "ProfileY" collection of my example.

You should adjust edmx properties naming and use the one representing the User has A profile relation, which shouldn't be a collection

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM