Ein Lambda-Ausdruck kann nicht als Argument für eine dynamisch ausgelöste Operation verwendet werden, ohne ihn zuvor in einen Delegaten- oder Ausdrucksbaumtyp umzuwandeln

78

Ich arbeite mit .NET4.5 und VS2013. Ich habe diese Abfrage, die das dynamicErgebnis von db erhält .

dynamic topAgents = this._dataContext.Sql(
    "select t.create_user_id as \"User\", sum(t.netamount) as \"Amount\" from transactiondetail t where t.update_date > sysdate -7 group by t.create_user_id")
    .QueryMany<dynamic>();

Die folgende Anweisung schlägt mit einem Kompilierungsfehler fehl, Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type ohne dass ich sie ausführen kann

topAgents.ToList().Select(agent => new
{
    User = agent.User != null ? string.Format("{0}", agent.User).Replace("CORPNTGB\\", "") : null,
    Amount = agent.Amount
});

während dieser mit foreachfunktioniert gut.

var data = new List<List<object>>();
foreach (dynamic agent in topAgents)
{
    data.Add(new List<object>
    {
        agent.User != null ? string.Format("{0}", agent.User).Replace("CORPNTGB\\", "") : null,
        agent.Amount
    });
}

In meinen Augen, nachdem ich topAgents.ToList()sie als gleichwertig interpretiert haben könnte, liegt es daran, var data = new List<List<object>>();dass ich ausdrücklich feststelle , dass diese zweite Anweisung vom Compiler zugelassen wird?

Warum erlaubt der Compiler keine LINQ-Auswahl, sondern jede?

Matas Vaitkevicius
quelle
2
Muss topAgentssein dynamic? Funktioniert es, wenn Sie varstattdessen verwenden?
DavidG

Antworten:

104

Das Problem ist , dass topAgentsist dynamic- so wird Ihr ToList()Anruf dynamisch ist, und so ist Select. Das hat Probleme, die:

  1. Sie können keine Lambda-Ausdrücke für solche dynamischen Aufrufe verwenden.
  2. Dynamische Aufrufe finden sowieso keine Erweiterungsmethoden.

Glücklicherweise müssen die Operationen nicht dynamisch sein, nur weil der Elementtyp dynamisch ist. Du könntest benutzen:

IEnumerable<dynamic> topAgents = ...;

... oder einfach benutzen var. Beides sollte in Ordnung sein.

Jon Skeet
quelle
Danke, ich habe irgendwie nicht gesehen, dass topAgents das die dynamicganze Zeit war.
Matas Vaitkevicius