我是 Linq 查询的新手,这个问题遇到了我(在其他开发人员被解雇之后)。 我正在使用一个货运 API,该 API 返回申请中每个产品/项目的“n”个货运价格列表。响应类别是:
public class FreightSimulation
{
public List<Item> Items { get; set; }
}
public class Item
{
public int Id { get; set; }
public List<ItemFreight> Freights { get; set; }
}
public class ItemFreight
{
public Company Company { get; set; }
public Type Type { get; set; }
public double Price { get; set; }
public int Days { get; set; }
public List<Error> Errors { get; set; }
}
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Type
{
public int Id { get; set; }
public string Description { get; set; }
}
public class Error
{
public string Message { get; set; }
}
我有一个 2 件物品的响应模型(但也可以是“n”件物品),其中一件有 5 种货运可能性,没有错误,但另一件有两个错误,这意味着一家公司没有货运服务对于该项目:
var response = new FreightSimulation
{
Items = new List<Item>
{
new Item
{
Id = 1,
Freights = new List<ItemFreight>
{
new ItemFreight
{
Errors = null,
Price = 10,
Days = 8,
Company = new Company
{
Id = 1
},
Type = new Type
{
Id = 3
}
},
new ItemFreight
{
Errors = null,
Price = 20,
Days = 3,
Company = new Company
{
Id = 1
},
Type = new Type
{
Id = 8
}
},
new ItemFreight
{
Errors = null,
Price = 20,
Days = 10,
Company = new Company
{
Id = 2
},
Type = new Type
{
Id = 1
}
},
new ItemFreight
{
Errors = null,
Price = 35,
Days = 4,
Company = new Company
{
Id = 2
},
Type = new Type
{
Id = 2
}
},
new ItemFreight
{
Errors = null,
Price = 15,
Days = 6,
Company = new Company
{
Id = 7468
},
Type = new Type
{
Id = 1
}
}
}
},
new Item
{
Id = 2,
Freights = new List<ItemFreight>
{
new ItemFreight
{
Errors = null,
Price = 10,
Days = 8,
Company = new Company
{
Id = 1
},
Type = new Type
{
Id = 3
}
},
new ItemFreight
{
Errors = null,
Price = 20,
Days = 3,
Company = new Company
{
Id = 1
},
Type = new Type
{
Id = 8
}
},
new ItemFreight
{
Errors = new List<Error>
{
new Error
{
Message = "Not found."
}
},
Company = new Company
{
Id = 2
},
Type = new Type
{
Id = 1
}
},
new ItemFreight
{
Errors = new List<Erro>
{
new Error
{
Message = "Not found."
}
},
Company = new Company
{
Id = 2
},
Type = new Type
{
Id = 2
}
},
new ItemFreight
{
Errors = null,
Price = 22,
Days = 4,
Company = new Company
{
Id = 7468
},
Type = new Type
{
Id = 1
}
}
}
}
}
};
我首先需要的是一个 Linq 查询,它带来一个列表,其中子列表在所有项目之间是通用的,并且其中没有错误。
在这种情况下,我有类似的东西:
Company Id Type Id Error
Item 1 1 3 N
Item 1 1 8 N
Item 1 2 1 N
Item 1 2 2 N
Item 1 7468 1 N
Item 2 1 3 N
Item 2 1 8 N
Item 2 2 1 Y
Item 2 2 2 Y
Item 2 7468 1 N
因此,在这种情况下,我需要一个列表,其中组合只有公司 1 和 7468(可能是“n”家公司)。因此,在第 2 项中,我的公司 2 响应有错误,因此必须将其消除。结果将是:
Company Id Type Id Error
Item 1 1 3 N
Item 1 1 8 N
Item 1 7468 1 N
Item 2 1 3 N
Item 2 1 8 N
Item 2 7468 1 N
任何组合公司/类型都可能发生这种情况,因此如果可能的话,它必须是某种动态查询。
您可以联系任何运费返回错误的公司:
var errorCompanyIds = response.Items
.SelectMany(x => x.Freights)
.Where(y => y.Errors !=null && y.Errors.Any())
.Select(y => y.Company.Id)
.ToList();
然后您可以创建新列表并过滤来自该公司的任何货运
var newList = new FreightSimulation
{
Items = response.Items.Select(x => new Item
{
Id = x.Id,
Freights = x.Freights.Where(y => !errorCompanyIds.Contains(y.Company.Id)).ToList()
}).ToList()
};
这应该有效:
var companyIds = new[] { 1, 7468 };
var result = response.Items.SelectMany(i => i.Freights.Select(f => new { itemId = i.Id, Freight = f }))
.Where(i => companyIds.Contains(i.itemId) && (!(i.Freight.Errors?.Any() ?? false)));
您在这里所做的是创建对来保留 id,然后根据您所需的条件过滤这些对。
或者,您可以先过滤原始货运列表,然后按公司挑选:
var companyIds = new[] { 1, 7468 };
var result = response.Items.SelectMany(i => i.Freights.Where(f => (!(f.Errors?.Any() ?? false)))
.Select(f => new { itemId = i.Id, Freight = f }))
.Where(i => companyIds.Contains(i.itemId));
以防万一这部分有点令人困惑:
(!(i.Freight.Errors?.Any() ?? false))
这本质上可以翻译为:
i.Freight.Errors == null || !i.Freight.Errors.Any()
表示货物有
null
错误或无错误(空集)。