[英]Linq - complex query - list in a list
我有这个课:
public class RecipeLine
{
public List<string> PossibleNames { get; set; }
public string Name { get; set; }
public int Index { get; set; }
}
我有多个RecipeLine对象的列表。 例如,其中一个看起来像这样:
Name: apple
PossibleNames: {red delicious, yellow delicious, ... }
Index = 3
我的数据库中还有一个名为tblFruit的表,该表有2列:名称和ID。 id与类中的索引不同。
我想做的是:对于RecipeLine对象的整个列表,在tblFruit中找到所有记录,这些记录的名称在“ PropertyNames”中,然后将类的索引和ID返回表中。 因此,我们在列表中有一个列表(具有字符串列表的RecipeLine对象的列表)。 如何在C#中使用Linq做到这一点?
我很确定不会有为此可以构造的LINQ语句,该语句将创建一个SQL查询以获取所需数据。 假设tblFruit没有太多的数据,拉下整个表并且用类似处理它在内存中...
var result = tblFruitList.Select((f) => new {Id = f.id, Index = recipeLineList.Where((r) => r.PossibleNames.Contains(f.name)).Select((r) => r.Index).FirstOrDefault()});
请记住,如果在“可能的名称”列表中没有带有tblFruit名称的配方线,则索引将为0。
不会将其单行放入讨厌的linq语句中的更具可读性的方法是...
Class ResultItem {
int Index {get;set;}
int Id {get;set;}
}
IEnumerable<ResultItem> GetRecipeFruitList(IEnumerable<FruitItem> tblFruitList, IEnumerable<RecipeLine> recipeLineList) {
var result = new List<ResultItem>();
foreach (FruitItem fruitItem in tblFruitList) {
var match = recipeLineList.FirstOrDefault((r) => r.PossibleNames.Contains(fruitItem.Name));
if (match != null) {
result.Add(new ResultItem() {Index = match.Index, Id = fruitItem.Id});
}
}
return result;
}
如果tblFruit包含大量数据,则可以尝试仅将那些在RecipeLine列表中可能名称列表中具有名称的项目下拉,例如...
var allNames = recipeLineList.SelectMany((r) => r.PossibleNames).Distinct();
var tblFruitList = DbContext.tblFruit.Where((f) => allNames.Contains(f.Name));
要获取表中Name
在“ PossibleNames
Name
所有水果,请使用以下命令:
var query = myData.Where(x => myRecipeLines.SelectMany(y => y.PossibleNames).Contains(x.Name));
我认为您不能一步一步做到这一点。
我首先创建一个可能的名称到索引的映射:
var possibleNameToIndexMap = recipes
.SelectMany(r => r.PossibleNames.Select(possibleName => new { Index = r.Index, PossbileName = possibleName }))
.ToDictionary(x => x.PossbileName, x => x.Index);
然后,我将从表中检索匹配的名称:
var matchingNamesFromTable = TblFruits
.Where(fruit => possibleNameToIndexMap.Keys.Contains(fruit.Name))
.Select(fruit => fruit.Name);
然后,您可以使用从表中检索到的名称作为原始地图的键:
var result = matchingNamesFromTable
.Select(name => new { Name = name, Index = possibleNameToIndexMap[name]});
不花哨,但应该易于阅读和维护。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.