使用LINQ从两个IEnumerables中选择

时间:2012-05-25 14:04:53

标签: c# .net linq entity-framework

这似乎相当容易,但我无法集中注意力 假设我有两个类定义如下:

class Class1
{
    public int Document;
    public decimal Amount;
}

class Class2
{
    public string Document;
    public decimal Amount;
}

定义了IEnumerable<Class1> result1IEnumerable<Class2> result2并填充了数据。

我有第三个类定义如下:

class ResultClass
{
    public string Document;
    public decimal? AmountFromClass1;
    public decimal? AmountFromClass2;
}

我想要一个LINQ查询,它从第一个结果中选择一些字段,从第二个结果中选择一些字段,并将它们放在定义为List<ResultClass> result的第三个结果中。
例如,如果我有第一个结果(result1)填充如下:

  Document    Amount
     1         1.55
     2         2.55

,第二个结果(result2)填充如下:

  Document    Amount
   "d-1"        1.22
   "d-2"        2.22

我希望最终result填充这样的内容(顺序无关紧要):

  Document    AmountFromClass1    AmountFromClass2
    "1"             1.55                null
   "d-1"            null                1.22
    "2"             2.55                null
   "d-2"            null                2.22

目前我使用两个foreach语句执行此操作,如下所示:

List<ResultClass> result = new List<ResultClass>();

foreach (var o in result1)
    result.Add(new ResultClass 
    { 
        Document = o.Document.ToString(), 
        AmountFromClass1 = o.Amount, 
        AmountFromClass2 = null 
    });

foreach (var o in result2)
    result.Add(new ResultClass 
    { 
        Document = o.Document, 
        AmountFromClass1 = null, 
        AmountFromClass2 = o.Amount 
    });

但我想用LINQ做这件事 有可能吗?

编辑:重新提出问题(还添加了 entity-framework 标签)
由于这只是一个代码示例,我知道在单个LINQ语句中执行此操作可能没有任何实际好处,因为它会执行相同的操作。
但是,我正在寻求性能改进,其中result1result2实际上是从LINQ到实体的IQueryables,所以我可以这样做:

List<ResultClass> MyFunc()
{
    Database DB = new Database(); // object context
    var result1 = DB.Class1s.Where(...);
    var result2 = DB.Class2s.Where(...);
    return SomeMagic()
        .Select(x => new ResultFunc { ... })
        .ToList();
}

3 个答案:

答案 0 :(得分:4)

将两个集合中的每个项目投影到一个ResultClass对象,并连接两个产生的枚举:

var query1 = from o in result1
             select new ResultClass
             {
                 Document = o.Document.ToString(),
                 AmountFromClass1 = o.Amount
             };

var query2 = from o in result2
             select new ResultClass
             {
                 Document = o.Document,
                 AmountFromClass2 = o.Amount
             };

var result = query1.Concat(query2).ToList();

答案 1 :(得分:1)

这是你转换成LINQ的代码

var result = result1
  .Select(c => new ResultClass() { Document = c.Document.ToString(), AmountFromClass1 = c.Amount })
  .Concat(result2.Select(c => new ResultClass() { Document = c.Document, AmountFromClass2 = c.Amount }))
  .ToList();

答案 2 :(得分:0)

根据您需要的输出,您似乎需要一个联盟

        var class1 = new List<Class1>();
        var class2 = new List<Class2>();
        class1.Add(new Class1 (){Document=1, Amount = 1.0M});
        class1.Add(new Class1 (){Document=2, Amount = 1.0M});
        class2.Add(new Class2 (){Document="1", Amount = 1.0M});
        class2.Add(new Class2 (){Document="3", Amount = 1.0M});
            var result = class1.Select(x=> new ResultClass{Document = x.Document.ToString(), AmountFromClass1=x.Amount, AmountFromClass2 = null}).Union(
                            class2.Select(x=> new ResultClass{Document = x.Document, AmountFromClass2=x.Amount, AmountFromClass1 = null})   );

如果您想要交叉连接,那么您可以使用带有多个from子句的查询语法。 Example