C# 使用LINQ从两个IEnumerable中选择

C# 使用LINQ从两个IEnumerable中选择,c#,.net,linq,entity-framework,C#,.net,Linq,Entity Framework,这似乎相当容易,但我无法集中注意力。 假设我有两个这样定义的类: class Class1 { public int Document; public decimal Amount; } class Class2 { public string Document; public decimal Amount; } class ResultClass { public string Document; public decimal? Amount

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

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

class Class2
{
    public string Document;
    public decimal Amount;
}
class ResultClass
{
    public string Document;
    public decimal? AmountFromClass1;
    public decimal? AmountFromClass2;
}
  Document    Amount
     1         1.55
     2         2.55
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 
    });
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();
}
IEnumerable result1
IEnumerable result2
定义并填充了数据

我有这样定义的第三个类:

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

class Class2
{
    public string Document;
    public decimal Amount;
}
class ResultClass
{
    public string Document;
    public decimal? AmountFromClass1;
    public decimal? AmountFromClass2;
}
  Document    Amount
     1         1.55
     2         2.55
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 
    });
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();
}
我需要一个LINQ查询,它从第一个结果中选择一些字段,从第二个结果中选择一些字段,并将它们放入定义为
列表结果的第三个结果中

例如,如果我的第一个结果(
result1
)是这样填充的:

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

class Class2
{
    public string Document;
    public decimal Amount;
}
class ResultClass
{
    public string Document;
    public decimal? AmountFromClass1;
    public decimal? AmountFromClass2;
}
  Document    Amount
     1         1.55
     2         2.55
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 
    });
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();
}
第二个结果(
result2
)的填充方式如下:

  Document    Amount
   "d-1"        1.22
   "d-2"        2.22
我希望最终的
结果
填充如下内容(顺序无关紧要):

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

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

class Class2
{
    public string Document;
    public decimal Amount;
}
class ResultClass
{
    public string Document;
    public decimal? AmountFromClass1;
    public decimal? AmountFromClass2;
}
  Document    Amount
     1         1.55
     2         2.55
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 
    });
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();
}

将两个集合中的每个项投影到一个
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();

将两个集合中的每个项投影到一个
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();

这是您转换为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();

这是您转换为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();

根据你需要的产出,你似乎需要一个工会

        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})   );
var class1=新列表();
var class2=新列表();
class1.Add(新的class1(){Document=1,Amount=1.0M});
类1.添加(新类1(){Document=2,Amount=1.0M});
类2.添加(新类2(){Document=“1”,金额=1.0M});
类2.添加(新类2(){Document=“3”,金额=1.0M});
var result=class1.Select(x=>newresultclass{Document=x.Document.ToString(),AmountFromClass1=x.Amount,AmountFromClass2=null}).Union(
class2.Select(x=>newresultclass{Document=x.Document,AmountFromClass2=x.Amount,AmountFromClass1=null});

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

基于您需要的输出,似乎您需要一个联盟

        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})   );
var class1=新列表();
var class2=新列表();
class1.Add(新的class1(){Document=1,Amount=1.0M});
类1.添加(新类1(){Document=2,Amount=1.0M});
类2.添加(新类2(){Document=“1”,金额=1.0M});
类2.添加(新类2(){Document=“3”,金额=1.0M});
var result=class1.Select(x=>newresultclass{Document=x.Document.ToString(),AmountFromClass1=x.Amount,AmountFromClass2=null}).Union(
class2.Select(x=>newresultclass{Document=x.Document,AmountFromClass2=x.Amount,AmountFromClass1=null});

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

从答案中可以看出,您完全可以在LINQ中完成这项工作,但它的代码量几乎完全相同,执行效率几乎完全相同。我不会费心去改变你的想法;现在一切都很好。也就是说,我会在代码中添加一些额外的空格,而不是在一行文本上做很多事情;它只是更难阅读。@Servy好的评论,我确实写了新行,更喜欢更容易阅读的代码,但是当我键入这个时我很匆忙,所以它看起来像这样也就不足为奇了。我现在正在编辑它。从答案中可以看出,你完全可以在LINQ中完成它,但它的代码量几乎完全相同,执行效率几乎完全相同。我不会费心去改变你的想法;现在一切都很好。也就是说,我会在代码中添加一些额外的空格,而不是在一行文本上做很多事情;它只是更难阅读。@Servy好的评论,我确实写了新行,更喜欢更容易阅读的代码,但是当我键入这个时我很匆忙,所以它看起来像这样也就不足为奇了。我现在正在编辑它。如果result1和result2将是从linq到实体的IQueryables,则此查询将在
select
上实际执行还是仅在
ToList()上执行?如果result1和result2将是从linq到实体的IQueryables,则此查询将在
select
上实际执行还是仅在
ToList()上执行?