Reputation: 3230
This seems fairly easy but I can't focus.
Let's say I have got 2 classes defined like this:
class Class1
{
public int Document;
public decimal Amount;
}
class Class2
{
public string Document;
public decimal Amount;
}
There are IEnumerable<Class1> result1
and IEnumerable<Class2> result2
defined and filled with data.
I have a third class defined like this:
class ResultClass
{
public string Document;
public decimal? AmountFromClass1;
public decimal? AmountFromClass2;
}
I want a LINQ query which selects some fields from the first result and some fields from the second result and puts them in a third result defined as List<ResultClass> result
.
For example, if I have the first result (result1
) populated like this:
Document Amount
1 1.55
2 2.55
and the second result (result2
) populated like this:
Document Amount
"d-1" 1.22
"d-2" 2.22
I want to have the final result
populated something like this (order doesn't matter):
Document AmountFromClass1 AmountFromClass2
"1" 1.55 null
"d-1" null 1.22
"2" 2.55 null
"d-2" null 2.22
Currently I do this using two foreach
statements, like this:
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
});
But I would like to do this using LINQ.
Is it possible?
EDIT: TO REFINE THE QUESTION (also added the entity-framework tag)
As this is just a code example, I am aware that there might be no real benefits of doing this in a single LINQ statement as it would do the same.
However, I am looking for a performance improvement where result1
and result2
are actually IQueryables from LINQ-to-Entities, in a way so I could do something like this:
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();
}
Upvotes: 1
Views: 1721
Reputation: 30728
Based on output you need, seems like you need an Union
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}) );
If you want cross join then you can use query syntax with multiple from clauses. Example
Upvotes: 0
Reputation: 5843
This is you code converted into 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();
Upvotes: 1
Reputation: 217401
Project each item in both collections to a ResultClass
object and concatenate the two resulting enumerables:
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();
Upvotes: 4