在LinQ Lambda Join中检索索引

时间:2014-06-17 10:25:59

标签: c# .net linq linq-to-sql lambda

我对所有的.Net内容都很陌生,只是想知道我想做些什么。 我一直在使用LinQ Lambda查询以使用Select语句返回列表值,如下所示:

        var data = list.Select((x, i) =>
            new
            {
                Index = i,       // <--- this is what I need!
                Value = x.Value,
                Text = x.Text
            })
            .ToList();

问题是我有一个LinQ Lambda Join表达式,如下所示:

        var data = DataBase.Table1
            .Join(DataBase.Table2,
                x => x.Id,
                y => y.Id,
                (x, y) => new    // <--- I can't do the same here :(
                {
                    Index = ???, // <--- Here is where I need the index!!
                    Value = x.Id,
                    Text = y.Description,
                })
            .OrderBy(x => x.Id)
            .ToList();

我的问题是,如何在第二个linq查询中检索索引,就像我在第一个查询中那样?

1 个答案:

答案 0 :(得分:1)

您无法将Select<T>(Func<T,int,bool>)与Linq for SQL一起使用。如果您尝试执行第一个查询,您将看到NotSupportedException:

  

用于查询运算符的不支持的重载'选择'

您可以将此运算符与Linq to Objects一起使用。只需使用AsEnumerable()调用将查询执行移至内存。在您收到连接结果并将执行移至内存后,使用第二个查询添加另一个投影:

 var data = DataBase.Table1
            .Join(DataBase.Table2,
                t1 => t1.Id,
                t2 => t2.Id,
                (t1, t2) => new { Value = t1.Id, Text = t2.Description }
            )
            .AsEnumerable() //otherwise next operator cannot be translated to SQL
            .Select((x,i) => new { x.Value, x.Text, Index = i})
            .OrderBy(x => x.Value)
            .ToList();

更新:如果您想要索引t2,那么您可以使用GroupJoin代替Join

 var data = DataBase.Table1
            .GroupJoin(DataBase.Table2,
                t1 => t1.Id,
                t2 => t2.Id,
                (t1, t2items) => new { Value = t1.Id, t2items }
            )
            .AsEnumerable() //otherwise next operator cannot be translated to SQL
            .SelectMany(x => x.t2items.Select((t2, i) => 
               new { x.Value, Text = t2.Description, Index = i}))
            .OrderBy(x => x.Value)
            .ToList();

如果您需要两个索引,则将整个联接移动到内存:

 var data = DataBase.Table1.AsEnumerable().Select((t1,i) => new { t1, i })
            .Join(DataBase.Table2.AsEnumerable().Select((t2,i) => new { t2, i }),
                  x1 => x1.t1.Id,
                  x2 => x2.t2.Id,
                  (x1, x2) => new { 
                      Value = x1.t1.Id, 
                      Text = x2.t2.Description,
                      Index1 = x1.i,
                      Index2 = x2.i
                  })
            .OrderBy(x => x.Value)
            .ToList();