2013-06-27 27 views
5

Próbuję połączyć 2 list od nich:Jak połączyć kwerendy LINQ z lambdas, które zwracają anonimowy typ?

var quartEst = Quarterly_estimates 
.OrderByDescending (q => q.Yyyy) 
.ThenByDescending (q => q.Quarter) 
.Where (q => 
    q.Ticker.Equals("IBM") 
    && 
    q.Eps != null 
    ) 
.Select (q => new { 
    ticker = q.Ticker, 
    Quarter = q.Quarter, 
    Year = q.Yyyy, 
    Eps = q.Eps}) 
.AsEnumerable() 
.Where (q => Convert.ToInt32(string.Format("{0}{1}", q.Year, q.Quarter)) > Convert.ToInt32(finInfo)); 

var quartAct = Quarterlies 
.OrderByDescending (q => q.Yyyy) 
.ThenByDescending (q => q.Quarter) 
.Where (q => 
    q.Ticker.Equals("IBM") 
    && 
    Convert.ToInt16(q.Yyyy) >= DateTime.Now.Year - 3 
    ) 
.Select (q => new { 
    Tick = q.Ticker, 
    Quarter = q.Quarter, 
    Year = q.Yyyy, 
    Eps = q.Eps_adj}) 
.AsEnumerable() 
.Where (q => Convert.ToInt32(string.Format("{0}{1}", q.Year, q.Quarter)) <= Convert.ToInt32(finInfo)); 

pojawia się błąd za pomocą prostego polecenia UNION:

var quartComb = quartEst.Union(quartAct); 

oto błąd:

Instance argument: cannot convert from 'System.Collections.Generic.List<AnonymousType#1>' to 'System.Linq.IQueryable<AnonymousType#2>' 

Co robić Muszę zrobić, aby osiągnąć to połączenie?

Odpowiedz

6

Aby użyć metody Union, kolekcje muszą mieć ten sam typ. Aby dwa typy anonimowe mogły być uważane za takie same, muszą mieć dokładnie tych samych członków o dokładnie takich samych typach.

Spróbuj tego:

var quartEst = Quarterly_estimates 
    ... 
    .Select (q => new { 
     Tick = q.Ticker,  // renamed ticker to Tick 
     Quarter = q.Quarter, 
     Year = q.Yyyy, 
     Eps = q.Eps}) 
    ... 

var quartAct = Quarterlies 
    .Select (q => new { 
     Tick = q.Ticker, 
     Quarter = q.Quarter, 
     Year = q.Yyyy, 
     Eps = q.Eps_adj}) 
    ... 

var quartComb = quartEst.Union(quartAct); 
+1

1+ Albo przemianowany ticker do Ticker? – Olrac

+0

@loy yep, to też zadziała. To naprawdę nie ma znaczenia, jakie jest imię, o ile jest takie samo. –

0

Aby rzucić dwóch różnych typów anonimowy Użytkownik może oddać go do dynamicznego, Oto kod poniżej

protected void Page_Load(object sender, EventArgs e) 
    { 
     List<AlertInfo> alert = new List<AlertInfo>(); 
     alert.Add(new AlertInfo() { StratId = 1, GroupId = 1 }); 
     alert.Add(new AlertInfo() { StratId = 1, GroupId = 2 }); 
     alert.Add(new AlertInfo() { StratId = 1, GroupId = 3 }); 
     alert.Add(new AlertInfo() { StratId = 2, GroupId = 1 }); 
     alert.Add(new AlertInfo() { StratId = 2, GroupId = 2 }); 
     alert.Add(new AlertInfo() { StratId = 2, GroupId = 3 }); 
     alert.Add(new AlertInfo() { StratId = 3, GroupId = 1 }); 
     alert.Add(new AlertInfo() { StratId = 3, GroupId = 2 }); 

     //To know how much data will get stored 
     var totalDataStore = alert.Select(x => x.StratId).Distinct().ToList(); 

     var result = alert.Where(x => x.StratId == 1).Select(x => new { Data1 = "Group" + x.StratId + x.GroupId }).Cast<dynamic>().Union(alert.Where(y => y.StratId == 2).Select(y => new { Data2 = "Group" + y.StratId + y.GroupId })).ToList(); 

    } 
} 

public class AlertInfo 
{ 
    public int StratId { get; set; } 
    public int GroupId { get; set; } 
}