我遇到了一个我喜欢理解它为什么会发生的问题。一些帮助将不胜感激。
我正在使用实体框架核心,这是我在代码中的查询:
var user = await _db.User
.Where(x => x.Email == username & x.Suspended == null)
.Select(x => new
{
x.UserId,
x.Password,
x.Salt,
Role = x.Role.Name
})
.SingleOrDefaultAsync();
此查询不会选择用户,但它不会抛出任何错误以太。如果我删除" x.Suspended" from Where子句比它将返回用户。
"暂停"是一个用户ID与用户表相关的表。用户ID是两个表中的PK,因此关系为1到1。
我认为此查询不会返回用户,因为x.Suspended为null。有人可以帮助我理解为什么会这样,以及我能做些什么来使它发挥作用。
更新: 好的,我使用的是SQL server profiler,这是按实体框架转换的sql:
exec sp_executesql N'SELECT [x.Suspended].[UserId], [x.Suspended].[RCD], [x.Suspended].[Reason], [x].[UserId], [x].[Password], [x].[Salt], [x.Role].[Name]
FROM [User] AS [x]
INNER JOIN [Role] AS [x.Role] ON [x].[RoleId] = [x.Role].[RoleId]
INNER JOIN [Suspended] AS [x.Suspended] ON [x].[UserId] = [x.Suspended].[UserId]
WHERE [x].[Email] = @__username_0',N'@__username_0 varchar(80)',@__username_0='some-username'
这里的问题是所有一对一关系都转换为INNER JOIN。我该如何处理这个问题?提前谢谢!
更新2: 我开始认为这是EF Core中的一个错误。例如,当我有这个:
var user = await _db.User
.Include(x => x.Role)
.Include(x => x.Suspended)
.Where(x => x.Email == username)
.SingleOrDefaultAsync();
在profiler下,sql输出是这样的:
exec sp_executesql N'SELECT TOP(2) [x].[UserId], [x].[Email], [x].[FirstName], [x].[LastName], [x].[Password], [x].[Phone], [x].[RCD], [x].[RoleId], [x].[Salt], [s].[UserId], [s].[RCD], [s].[Reason], [r].[RoleId], [r].[Name]
FROM [User] AS [x]
LEFT JOIN [Suspended] AS [s] ON [s].[UserId] = [x].[UserId]
INNER JOIN [Role] AS [r] ON [x].[RoleId] = [r].[RoleId]
WHERE [x].[Email] = @__username_0',N'@__username_0 varchar(80)',@__username_0='user-email'
显然"暂停"表是左连接而不是内部。但是当我有这个:
var user1 = await _db.User
.Include(x => x.Role)
.Include(x => x.Suspended)
.Where(x => x.Email == username & x.Suspended == null)
.SingleOrDefaultAsync();
sql profiler下的sql是:
SELECT [x].[UserId], [x].[Email], [x].[FirstName], [x].[LastName], [x].[Password], [x].[Phone], [x].[RCD], [x].[RoleId], [x].[Salt], [x.Suspended].[UserId], [x.Suspended].[RCD], [x.Suspended].[Reason], [s].[UserId], [s].[RCD], [s].[Reason], [r].[RoleId], [r].[Name]
FROM [User] AS [x]
INNER JOIN [Suspended] AS [x.Suspended] ON [x].[UserId] = [x.Suspended].[UserId]
LEFT JOIN [Suspended] AS [s] ON [s].[UserId] = [x].[UserId]
INNER JOIN [Role] AS [r] ON [x].[RoleId] = [r].[RoleId]
什么是混乱:-我们到底怎么了"暂停"表连接两次,INNER和LEFT? WHERE子句在哪里?
SELECT U.[UserId], U.[Password], U.[Salt], R.[Name] AS [Role]
FROM [ag].[dbo].[User] AS U
INNER JOIN [ag].[dbo].[Role] AS R ON U.[RoleId] = R.[RoleId]
LEFT JOIN [ag].[dbo].[Suspended] AS S ON U.[UserId] = S.[UserId]
WHERE U.[Email] = 'john.smith@gmail.com' AND S.[UserId] IS NULL
答案 0 :(得分:0)
您应该使用&&
{{1}}
答案 1 :(得分:0)
我是对的,这是一个错误,将在未来的EF核心版本中修复。以下是 github 上问题的链接。