【问题标题】:How do I instruct Entity Framework to select the correct relationship between two tables with multiple foreign keys between them?如何指示实体框架选择两个表之间的正确关系,它们之间有多个外键?
【发布时间】:2016-02-11 22:57:46
【问题描述】:

我有一个使用数据库优先方法生成的实体框架设置。其中我有一个用户表和一个配置文件表。

User
- UserId
- ProfileId

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

在每个表中,ID 都是它们的主键。问题是两个表之间存在 3 个外键关系。

  1. 用户有个人资料 (User.FK_User_Profile User.ProfileId == Profile.ProfileId)
  2. 用户创建了配置文件 (Profile.FK_UserCreatedBy Profile.CreatedBy == User.UserId)
  3. 用户修改了配置文件 (Profile.FK_UserModifiedBy Profile.ModifiedBy == User.UserId)

这一切都在数据库中正常工作。不幸的是,当我尝试使用以下 Linq 查询访问由此生成的 edmx 时:

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

生成的sql是这样的:

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]

问题在于左外连接标准。而不是加入

Extent1.UserId = Extent2.UserId

它正在加入

Extent1.UserId = Extent2.ModifiedBy

这导致 Linq 检索所有修改配置文件的用户,而不是用户拥有的配置文件。

如何指示 EF 正确映射此查询,或更可能是这些关系?

【问题讨论】:

  • 可以添加User和Profile类的定义吗?你在属性中使用了什么属性?
  • 请显示生成的 edmx。如果用户有 1 个配置文件,那么您使用的导航属性是错误的,因为您正在执行 firstordefault,这是用于集合而不是用于导航属性(我的意思是 Profile 道具是一个集合,因此它代表 1:N 配置文件与用户关系之一)

标签: c# .net sql-server entity-framework linq-to-sql


【解决方案1】:

由于您没有包含有关生成的 edmx 的任何信息,我将尝试猜测..: 这些表的模型应该在 User 类上产生类似这样的东西:

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

根据您发布的 Sql,您的 linq 的“Profile.FirstOrDefault”是我示例的“ProfileY”集合。

您应该调整 edmx 属性命名并使用代表用户的配置文件关系,它不应该是一个集合

【讨论】:

  • 您为我指明了正确的方向。 edmx 确实生成了 Profile、Profile1 和 Profile2。正如预期的那样,它使用 FK_Profile_UserModified_By 键,而不是使用 FK_User_Profile 键的 Profile。 Profile1 正在使用正确的 FK_User_Profile 密钥。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-20
  • 2015-03-27
相关资源
最近更新 更多