linq selectmany压平多个级别

时间:2016-10-24 15:32:11

标签: c# linq

我有以下关系(例如)

A包含一个或多个B&#39>

每个B包含一个或多个C和D

我想使用SelectMany将所有内容与一些搜索条件拼平,然后获得A,B,C和D。这就是我所拥有的。

context.A.Where(a => (string.IsNullOrEmpty(name) || a.Name.Contains(name)))
    .SelectMany(ab =>ab.b.Where(n=>n.bname.Contains(name) || string.IsNullOrEmpty(name)),     
    (aa, bb) => new { aa, bb })   //gets all a's and b's
    .SelectMany(bc => bb.c.Where(w => w.KEYWORD.Contains(Keyword) || string.IsNullOrEmpty(Keyword)),
    (bc,words) => new {bc,kwords})  //gets all b's and c's

我做得对吗?如果是这样,那么如何将B与所有D添加到上面的表达式一起?

2 个答案:

答案 0 :(得分:2)

使用Lambda语法选择数据:

var flatData = context.A.SelectMany(a => a.B.SelectMany(b => b.Select(new {a,b,c = b.C,d = b.D})

更进一步,在应用Where条款之前,应进行以下检查,因为它们会检查提供的常量输入,namekeyword

  1. string.IsNullOrEmpty(name)
  2. string.IsNullOrEmpty(keyword)
  3. 剩下的检查很简单:

    if(!string.IsNullOrEmpty(name))
        flatData  = flatData.Where(data => data.a.Name.Contains(name))
                            .Where(data => data.b.Name.Contains(name));
    
    if(!string.IsNullOrEmpty(keyword))
       flatData  = flatData.Where(data => data.c.Keyword.Contains(keyword));
    

    要点:

      上面的
    • flatData有一个级联过滤器,首先在a.Name, b.Name and c.Keyword

答案 1 :(得分:1)

同意伊万的建议,你可以将这三层深层结构压扁:

var query = (from a in A
             from b in (List<dynamic>)a.b
             from c in (List<dynamic>)b.c
             from d in (List<dynamic>)b.d
             select new { a, b, c, d });

if (!string.IsNullOrEmpty(name))
{
    query = query.Where(record => record.b.bname.Contains(name));
}

if (!string.IsNullOrEmpty(keyword))
{
    query = query.Where(record => record.c.keyword.Contains(keyword));
}

var result = query.ToList();

您还可以在顶部的查询中添加where子句,但看到您正在检查是否有任何有效输入我将其放在 <之后/ p>

使用此示例数据进行测试:

List<dynamic> A = new List<dynamic>
{
    new { b = new List<dynamic> { new { bname = "a", c = new List<dynamic> { new { keyword = "b" } }, d = new List<dynamic> { 1, 2, 3 } } } },
    new { b = new List<dynamic> { new { bname = "a", c = new List<dynamic> { new { keyword = "d" } }, d = new List<dynamic> { 1, 2, 3 } } } }
};

string name = "a";
string keyword = "b";