C#LINQ。按对象名称属性或名称部分搜索对象

时间:2017-08-03 20:39:36

标签: c# linq object search

我正在尝试查找买家的所有发票,按买家名称搜索(包含和等于过滤器)。寻找最干净的方法来做到这一点。 我有一份买家名单。

List <Buyer> AllBuyers;

买方是:

public class Buyer
    {
        public string BuyerIdentifier{ get; set; }
        public string Name { get; set; }
    }

我有买家发票清单。

List <Invoice> AllInvoices;

发票是

public class Invoice
    {
        public string InvoiceID { get; set; }
        public string BuyerID { get; set; }
        public string Amount{ get; set; }
    }

我目前在做什么:

List<string> BuyerIDs = new List<string> { };
foreach (Invoice inv in AllInvoices)
{
    if (!(BuyerIDs.Contains(inv.BuyerID)))
    {
         // add BuyerID to list if it's not already there. Getting id's that are present on invoices and whose Buyer names match using contains or equals
        BuyerIDs.Add(AllBuyers.First(b => b.BuyerIdentifier == inv.BuyerID
          && (b.Name.IndexOf(SearchValue, StringComparison.OrdinalIgnoreCase) >= 0)).BuyerIdentifier);
    }                                                
 }
 Invoices = AllInvoices.FindAll(i=> BuyerIDs.Contains(i.BuyerID));

LINQ查询语法比LINQ方法更容易理解。所以在下面的回复后我现在这样做:

Invoices  =  (from buyer in AllBuyers
              join invoice in AllInvoices on buyer.BuyerIdentifier equals invoice.BuyerID
              where buyer.Name.IndexOf(SearchValue, StringComparison.OrdinalIgnoreCase) >= 0                                 
              select invoice).ToList();

4 个答案:

答案 0 :(得分:2)

如果您只需要发票,则可以加入两个集合,过滤并选择发票

AllBuyers.Join(AllInvoices, 
            a => a.BuyerIdentifier, 
            a => a.BuyerID, 
            (b, i) => new { Buyer = b, Invoice = i })
    .Where(a => a.Buyer.Name.Contains("name"))
    .Select(a => a.Invoice).ToList();

如果您也想要买家,请忽略.Select(a => a.Invoice)。 字符串的Contains方法也会匹配等号。

答案 1 :(得分:1)

这是一个建议,我使用BuyerIdentifier作为键创建一个字典,并将发票列表作为值:

var dict = AllBuyers.ToDictionary(k => k.BuyerIdentifier,
                v => AllInvoices.Where(i => i.BuyerID == v.BuyerIdentifier).ToList());

然后您可以访问特定买家的发票清单,如下所示:

List<Invoice> buyerInvoices = dict[buyerId];

答案 2 :(得分:0)

这应该适合你:

var InvoiceGrouping = AllInvoices.GroupBy(invoice => invoice.BuyerID)
                                 .Where(grouping => AllBuyers.Any(buyer => buyer.BuyerIdentifier == grouping.Key && buyer.Name.IndexOf(pair.Value, StringComparison.OrdinalIgnoreCase) >= 0));

您最终得到的是一个分组,其中有一个买方的ID作为密钥,所有的发票都是值。

如果您只想要一张发票清单,您可以这样做:

var Invoices = AllInvoices.GroupBy(invoice => invoice.BuyerID)
                          .Where(grouping => AllBuyers.Any(buyer => buyer.BuyerIdentifier == grouping.Key && buyer.Name.IndexOf(pair.Value, StringComparison.OrdinalIgnoreCase) >= 0))
                          .SelectMany(grouping => grouping);

请注意最后添加的SelectMany,因为IGrouping实现IEnumerable,会将分组展平为单个枚举值。

答案 3 :(得分:0)

作为ILookup粉丝,这将是我的方法:

var buyerMap = AllBuyers
    .Where(b => b.Name.IndexOf(SearchValue, StringComparison.OrdinalIgnoreCase) >= 0)
    .ToDictionary(b => b.BuyerIdentifier);

var invoiceLookup = AllInvoices
    .Where(i => buyerMap.ContainsKey(i.BuyerID))
    .ToLookup(x => x.BuyerID);

foreach (var invoiceGroup in invoiceLookup)
{
    var buyerId = invoiceGroup.Key;
    var buyer = buyerMap[buyerId];
    var invoicesForBuyer = invoiceGroup.ToList();

    // Do your stuff with buyer and invoicesForBuyer
}