【发布时间】:2016-02-11 22:57:46
【问题描述】:
我有一个使用数据库优先方法生成的实体框架设置。其中我有一个用户表和一个配置文件表。
User
- UserId
- ProfileId
Profile
- ProfileId
- {unimportant profile details}
- ModifiedOn
- CreatedOn
在每个表中,ID 都是它们的主键。问题是两个表之间存在 3 个外键关系。
- 用户有个人资料 (User.FK_User_Profile User.ProfileId == Profile.ProfileId)
- 用户创建了配置文件 (Profile.FK_UserCreatedBy Profile.CreatedBy == User.UserId)
- 用户修改了配置文件 (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