Linq - 复杂查询 - 列表中的列表

时间:2015-07-27 13:43:13

标签: c# linq

我有这堂课:

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的表,它有两列:name和id。 id与类中的索引不同。

我想做的是: 对于RecipeLine对象的整个列表,找到名称在PossibleNames中的tblFruit中的所有记录,并返回该类的索引和表中的id。所以我们在列表中有一个列表(具有字符串列表的RecipeLine对象列表)。如何在c#中使用Linq执行此操作?

3 个答案:

答案 0 :(得分:1)

我非常确定不会有一个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名称的recipeLine,其索引将为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));

答案 1 :(得分:0)

要获得Name位于PossibleNames的表格中的所有结果,请使用以下内容:

var query = myData.Where(x => myRecipeLines.SelectMany(y => y.PossibleNames).Contains(x.Name));

答案 2 :(得分:0)

我认为你不能一步到位。

我首先要为索引创建一个可能名称的地图:

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]});

不花哨,但应该易于阅读和维护。