繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM