【问题标题】:Filter IEnumerable Collection using Linq on ASP.NET Web API 2在 ASP.NET Web API 2 上使用 Linq 过滤 IEnumerable 集合
【发布时间】:2017-07-13 18:23:28
【问题描述】:

我需要在 ASP.NET Web Api 2 C# 上使用 Linq 根据布尔条件过滤我的数据。但是当我尝试过滤数据时,我的 JSON 数据返回 null。

数据是邀请列表,我想根据 MemberID 和用户是否参加(IsAttending)过滤结果

这是成员模型

public class Member
{
    public int MemberID { get; set; }
    public string MemberName { get; set; }
    public bool IsAdmin { get; set; }
    public bool IsAttending { get; set; }
    public int MemberNumber { get; set; }
    public string PhoneNumber { get; set; }
    public int InviteID { get; set; }
    [JsonIgnore]
    public virtual Invite Iinvite { get; set; }
}

邀请模特

public class Invite
{
    public int InviteID { get; set; }
    public string Subject { get; set; }
    public string DateTime { get; set; }
    public virtual List<Member> Members { get; set; }
}

未经过滤的原始 JSON 数据

[{
    "InviteID": 1,
    "Subject": "Hell",
    "DateTime": "March 2017",
    "Members": [{
        "MemberID": 1,
        "MemberName": "roger",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 1
    },
    {
        "MemberID": 2,
        "MemberName": "nkosi",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 1
    },
    {
        "MemberID": 3,
        "MemberName": "Mphile",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 1
    }]
},
{
    "InviteID": 2,
    "Subject": "Hell",
    "DateTime": "March 2018",
    "Members": [{
        "MemberID": 4,
        "MemberName": "roger",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 2
    },
    {
        "MemberID": 5,
        "MemberName": "nkosi",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 2
    },
    {
        "MemberID": 6,
        "MemberName": "Mphile",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 2
    }]
},
{
    "InviteID": 3,
    "Subject": "Hell",
    "DateTime": "Marchs 2017",
    "Members": [{
        "MemberID": 7,
        "MemberName": "Roger Nkosi",
        "IsAdmin": false,
        "IsAttending": true,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 3
    },
    {
        "MemberID": 8,
        "MemberName": "nkosi",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 3
    },
    {
        "MemberID": 9,
        "MemberName": "Mphile",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 3
    }]
},
{
    "InviteID": 4,
    "Subject": "Hell",
    "DateTime": "Marchs 2017",
    "Members": [{
        "MemberID": 10,
        "MemberName": "Roger Nkosi",
        "IsAdmin": false,
        "IsAttending": true,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 4
    },
    {
        "MemberID": 11,
        "MemberName": "nkosi",
        "IsAdmin": false,
        "IsAttending": true,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 4
    },
    {
        "MemberID": 12,
        "MemberName": "Mphile",
        "IsAdmin": false,
        "IsAttending": true,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 4
    }]
}]

这是我过滤和返回数据的方式

return db.invites.Include("members").ToList()
                .Where(x => x.Members == db.members
                                .Where(xx => xx.IsAttending == true && xx.MemberID == 4)).ToList();

【问题讨论】:

  • 您的预期结果是什么?您的 LINQ 查询将永远不会返回任何结果,因为您正在通过引用比较集合。请在您的问题中添加一个示例,说明过滤后 Json 的外观。
  • 这个怎么放?我希望我的 JSON 相同,但包括成员 ID 匹配的成员和 IsAttending == true
  • 如果某个特定邀请的成员同时具有IsAttending 真假,会发生什么情况?目前尚不清楚您希望过滤结果的深度,这就是我要求您在问题中添加预期结果的原因。
  • 如果成员属性 IsAttending == false,则该成员不会成为返回 JSON 数据的一部分。
  • 在原始 JSON 中,您永远不会有 IsAttending == true &amp;&amp; MemberID == 4

标签: c# entity-framework linq asp.net-web-api


【解决方案1】:

您想要的并非不可能,只是通过对 DB 的单个 LINQ 查询无法实现。

假设 memberId 包含您要过滤的成员的 id:

var invites = db.invites.Include(i => i.Members).Where(i => i.Members.Any(m => m.IsAttending && m.MemberID == memberId)).ToList(); // db query
invites = invites.Select(i =>
    new Invite
    {
        DateTime = i.DateTime,
        InviteID = i.InviteID,
        Subject = i.Subject,
        Members = i.Members.Where(m => m.IsAttending && m.MemberID == memberId).ToList()
    }).ToList(); // this removes other members (in memory)

 return invites;

【讨论】:

  • 我只会在第一个查询中包含成员,以避免 n+1 个请求...
【解决方案2】:

您应该使用 Linq Any() 运算符。

它看起来更像

return db.invites.Include("members").Where(x => x.Members.Any(xx => xx.IsAttending && xx.MemberID == 4).ToList()

顺便说一句,我在 db.invites 之后删除了 ToList(),因为这会导致整个成员集合被枚举。不确定您的数据库有多大,但这最终会成为问题。

【讨论】:

  • 这行得通,但我需要结果的方式是,如果(xx =&gt; xx.IsAttending &amp;&amp; xx.MemberID == 4) 返回 true,它将返回邀请,但我需要不包含 (xx =&gt; xx.IsAttending &amp;&amp; xx.MemberID == 4) == false 的用户结果。
猜你喜欢
  • 2017-10-09
  • 1970-01-01
  • 2022-11-26
  • 1970-01-01
  • 2011-12-30
  • 1970-01-01
  • 2011-04-21
  • 2012-04-08
  • 1970-01-01
相关资源
最近更新 更多