Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么这个LINQ查询无法工作?_C#_Linq_Async Await_Entity Framework Core - Fatal编程技术网

C# 为什么这个LINQ查询无法工作?

C# 为什么这个LINQ查询无法工作?,c#,linq,async-await,entity-framework-core,C#,Linq,Async Await,Entity Framework Core,我遇到了一个问题,我想知道为什么会这样。我们将非常感谢您的帮助 我使用的是实体框架核心,这是我在代码中的查询: var user = await _db.User .Where(x => x.Email == username & x.Suspended == null) .Select(x => new { x.UserId, x.Password, x.Salt,

我遇到了一个问题,我想知道为什么会这样。我们将非常感谢您的帮助

我使用的是实体框架核心,这是我在代码中的查询:

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();

此查询不会选择用户,但不会引发任何错误。如果我从Where子句中删除“x.Suspended”,它将返回用户。 “Suspended”是一个通过用户ID与用户表相关的表。用户ID在两个表中都是PKs,因此关系为1:1。 我认为这个查询不会返回用户,因为x.Suspended是空的。有人能帮助我理解为什么会发生这种情况,以及我能做些什么来让它起作用

更新: 好的,我使用了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'
这里的问题是,所有一对一关系都转换为内部联接。我如何处理这个问题?提前谢谢

更新2: 我开始认为这是EF核心中的一个bug。例如,当我有这个:

var user = await _db.User
      .Include(x => x.Role)
      .Include(x => x.Suspended)
      .Where(x => x.Email == username)
      .SingleOrDefaultAsync();
 var user1 = await _db.User
       .Include(x => x.Role)
       .Include(x => x.Suspended)
       .Where(x => x.Email == username & x.Suspended == null)
       .SingleOrDefaultAsync();
在探查器下,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 user = await _db.User
      .Include(x => x.Role)
      .Include(x => x.Suspended)
      .Where(x => x.Email == username)
      .SingleOrDefaultAsync();
 var user1 = await _db.User
       .Include(x => x.Role)
       .Include(x => x.Suspended)
       .Where(x => x.Email == username & x.Suspended == null)
       .SingleOrDefaultAsync();
sql探查器下的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]
真是一团糟:-D我们他妈的怎么把“悬浮”的桌子连了两次,里边和左边?where子句在哪里

我只想让这一切在LINQ发挥作用: 你应该使用&&

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();
你应该使用&&

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();


我是对的,这是一个错误,将在未来的EF核心版本中修复。这里是关于

问题的链接,我的观点是正确的,这是一个bug,将在未来的EF core版本中修复。这是关于

的问题的链接,也尝试过了,没有帮助。嗯,挂起的是空的吗?如果它不为null,它就工作,但是如果它为null,它就不工作。请参阅我发布的数据库的模式。这不是一个布尔值。@Arman可能需要从主菜单中检查您的suspended.userid和useridtable@Sajeetharan如果用户已挂起,则应在挂起表中为该用户保留一条记录。此特定用户未挂起,因此该表中没有记录,因此在本例中,x.suspended为null。我可能需要查看探查器,看看发送到服务器的sql是什么。也尝试过了,没有帮助。嗯,挂起的是空的吗?如果它不为null,它就工作,但是如果它为null,它就不工作。请参阅我发布的数据库的模式。这不是一个布尔值。@Arman可能需要从主菜单中检查您的suspended.userid和useridtable@Sajeetharan如果用户已挂起,则应在挂起表中为该用户保留一条记录。此特定用户未挂起,因此该表中没有记录,因此在本例中,x.suspended为null。我可能需要查看探查器,看看发送到服务器的sql是什么。但是
内部连接将完全满足您的需要-删除
为null的行
挂起的行
。唯一让我吃惊的是
Role
表上的
internaljoin
,我认为这是由
Select
子句中的
x.Role.Name
引起的。尝试
Role=x。Role==null?null:x.Role.Name
,但我不确定这是否有帮助。用户和挂起之间的关系是1..0-1而不是1:1 Hanks Robert,这里的想法是,如果用户被挂起,则记录应该在“挂起”表中,并带有原因和日期。此查询用于身份验证,在对用户进行身份验证并提供令牌(jwt)之前,我需要确保用户未挂起。内部连接在这里毫无帮助。我确实理解他们为什么这样设计。角色是一个自己喜欢的表,与用户一对一的关系暂停。唯一的区别是用户记录有RoleId列。EF似乎将所有一对一关系转换为内部联接。是的,因为所有1:1关系本质上都是一个内部联接。但是,
内部联接
将完全满足您的需要-删除带有
null的行
挂起
。唯一让我吃惊的是
Role
表上的
internaljoin
,我认为这是由
Select
子句中的
x.Role.Name
引起的。尝试
Role=x。Role==null?null:x.Role.Name
,但我不确定这是否有帮助。用户和挂起之间的关系是1..0-1而不是1:1 Hanks Robert,这里的想法是,如果用户被挂起,则记录应该在“挂起”表中,并带有原因和日期。此查询用于身份验证,在对用户进行身份验证并提供令牌(jwt)之前,我需要确保用户未挂起。内部连接在这里毫无帮助。我确实理解他们为什么这样设计。角色是一个自己喜欢的表,与用户一对一的关系暂停。唯一的区别是用户记录有RoleId列。EF似乎将所有一对一关系转换为内部联接。是的,因为所有1:1关系本质上都是内部联接。