gpt4 book ai didi

c# - LINQ - EF Core - 返回包含嵌套列表中的两个对象(由属性引用)的对象

转载 作者:行者123 更新时间:2023-12-04 07:42:40 24 4
gpt4 key购买 nike

我知道有 100 万个 LINQ 问题,所以我很抱歉问这个问题。我环顾四周,我无法找到正确的答案。我怀疑这很容易,但我是 LINQ 和 EF 核心的新手。
我有以下从数据库查询返回的 Room 类型列表(为简洁起见,我只包含一个):

[
{
"roomId": 2,
"roomName": "test",
"users": [
{
"userId": 2,
"username": "seconduser",
"password": "demo",
"token": null,
"refreshToken": null,
"alias": "test",
"friends": null
},
{
"userId": 3,
"username": "thirduser",
"password": "demo",
"token": null,
"refreshToken": null,
"alias": "test",
"friends": null
}
]
}
]
伟大的。我想要一个 LINQ 查询(最好使用流畅的语法,但我很感激任何帮助),它将使用更多 Room 查询此列表并仅返回一个(我知道只会有一个)满足以下条件:
房间里只有两个用户,而且这两个用户都是通过传入方法的 userId 来标识的。
因此,如果该方法接收到以下对象:
{
"friendId": 1,
"requestUserId": 3
}
上面引用的房间将被退回,没有其他的。
我希望这很清楚。
提前致谢!
编辑 - 很公平,我现在包括一些让我更接近的尝试
我尝试填充两个用户,以便我可以询问 room.Users.Contains() 是否像这样:
var requestingUser = UserService.GetSingleUser(request.RequestUserId);

var friendUser = UserService.GetSingleUser(srequest.FriendId);

var test = allRooms.FirstOrDefault(room => room.Users.Count == 2 && room.Users.Contains(friendUser) && room.Users.Contains(requestingUser);
但是,用户的比较没有通过。这只是我如何填充用户的问题吗?无论如何,我知道我不应该这样做。
然后我尝试了在方向上看起来像是严格的方法,只是像这样比较 ID:
var test = allRooms.First(room => room.Users.Any(user =>
user.userId == request.FriendId && user.userId == request.RequestUserId));
但这会返回 null,但我已经确认有一个房间满足我指定的条件。
给我带来麻烦的是EF核心生成了一个我不熟悉的数据库模式。仅在 SQL 中,我会将表 ROOM、USER、ROOMUSER 和内部连接到 ROOMUSER,其中 USER.id 都存在......并且不同,或者无论如何。
进一步编辑:
我包括我用来构建下面的数据库的模型。最初我没有,因为我包含的 JSON 是查询所有房间并包括他们的用户(房间内的 ICollection)的结果。
    public class User
{
public int UserId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Token { get; set; }
public string RefreshToken { get; set; }
public string Alias { get; set; }

public ICollection<User> Friends { get; set; }
}

public class Room
{
public int RoomId { get; set; }
public string RoomName { get; set; }

public ICollection<User> Users { get; set; }
}
因此,正如我所描述的如果我手工制作表格会是什么样子,这个想法是用户和房间是不同的实体(主要实体),并且会有一个连接表来表明它们的关系。从概念上讲,用户在房间里。
可能使事情更清楚的是以下 LINQ 返回的初始 JSON:
var allRooms = db.Rooms.Include(x => x.Users).ToList();
因此,要求具有上述条件的房间应该不会太难。
诚然,正如我所说,我从来没有使用过 EF 核心,也几乎没有使用过 LINQ。我可能犯了一个愚蠢的错误......

最佳答案

这个很近

room => room.Users.Any(user =>
user.userId == request.FriendId && user.userId == request.RequestUserId)
但需要一些调整
  • 并且 ( && ) 运算符不合适 - id 不能同时等于传递的两个 id。它应该是一个或另一个,即您需要的是 Or ( || ) 运算符
    user.userId == request.FriendId || user.userId == request.RequestUserId
  • Any也不合适。它会返回一个房间,其中只有一个通过的用户,或者两者都有,但里面还有其他用户。您需要的是All反而。
    房间。用户。所有(用户=>
    user.userId == request.FriendId || user.userId == request.RequestUserId)

  • 然而 All对于空集也返回 true(即当 room.Users 为空时),所以它必须与另一个调用结合以消除这种情况
    room.Users.Any() && room.Users.All(user =>
    user.userId == request.FriendId || user.userId == request.RequestUserId)
    这将产生所需的结果,但效率低下,因为涉及两个子查询而不是一个。
    因此,最好的方法是使用我所说的“条件计数”并将结果计数与两 (2) 进行比较:
    room.Users.Count(user =>
    user.userId == request.FriendId || user.userId == request.RequestUserId) == 2
    也可以用这样的输入更一般地表达(因为它支持超过 2 个)
    // could contain more than two ids and doesn't need to be array
    var userIds = new [] { request.FriendId, request.RequestUserId }.AsEnumerable();
    和查询条件如
    room.Users.Count(user => userIds.Contains(user.userId)) == userIds.Count()

    关于c# - LINQ - EF Core - 返回包含嵌套列表中的两个对象(由属性引用)的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67377074/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com