需要linq查询

时间:2016-10-03 16:40:55

标签: linq c#-4.0

我在列表中有3个字段(Name,Code,displayNmae),这里我需要获取一个列表作为输出,其中我得到所有字段但需要用冒号分割displayname字段然后再为每个分割添加列表值是显示名称。 因此,在输出列表中,我将有5行,因为总显示名称是2行中的5。 需要linq查询此问题。

名称代码displayName

Napkins_tableware - 餐巾和餐具 - 3_ply:conventional_napkins

手巾 - 手巾和毛巾 - 2_ply:毛巾卷:彩色

输出应该是这样的:

名称 代码displayName

Napkins_tableware - 餐巾和餐具 - 3_ply

Napkins_tableware - 餐巾和餐具 - conventional_napkin

手巾 - 手巾 - 2_ply

手巾 - 手巾 - 毛巾卷

手巾 - 手巾和毛巾

我在C#中试过的解决方案

foreach(ProductDetailsWithFilters qs in CategoryProductList())
{
    foreach(string friendlyname in qs.displayName.Split(':'))
    {
        qs.displayName = friendlyname;
        tempCategoryProductList.Add(qs);
    }
}

1 个答案:

答案 0 :(得分:1)

如果你正在翻译LINQ,当你有嵌套的foreach循环时,它们对应于查询语法中的'from'子句(或者在点语法中,后续的变成SelectMany,见下文。)以下内容应该接近你的内容想:

var query = 
    from qs in CategoryProductList()
    from friendlyName in qs.displayName.Split(':')
    select new ProductDetailsWithFilters(qs.Code, qs.Category, friendlyName);

注意:由于函数式编程应该是无副作用的,因此最好选择一个新实例ProductDetailsWithFilters,而不是修改查询中的现有实例。我的假设是你可以调用构造函数来构建一个新的构造函数。

为了修改现有属性,就像你的循环实现那样,你必须迭代结果 - LINQ在框架中没有提供这样的东西。这种副作用通常会导致难以发现的错误。

使用SelectMany和dot-syntax执行上述查询的等效操作:

var query = CategoryProductList()
    .SelectMany(
        qs => qs.DisplayName.Split(':'),
        (qs, friendlyName) => new ProductDetailsWithFilters(qs.Code, qs.Category, friendlyName));

两者都导致功能相同的代码。在这种情况下,我更倾向于使用点语法的查询语法,部分原因是因为有几个SelectMany重载并且处理投影涉及在两个lambda表达式中重复变量。如果您要添加另一个“from”,则查询语法会隐藏“透明标识符”的管理,否则您必须在点语法等效代码中处理这些标识符。无论你喜欢什么,你现在都有。

值得注意的是,查询是懒惰的 - 在迭代结果之前,它们什么都不做。所以你真的用这里的结果来做这个有趣的部分 - 存储它.ToList(),直接数据绑定到UI,用它来为web-API提供服务......等等。