web-dev-qa-db-ja.com

最初にデリゲートまたは式ツリー型にキャストせずに、動的にディスパッチされる操作の引数としてラムダ式を使用することはできません

私は.NET4.5とVS2013で作業しています。このクエリは、dbからdynamicの結果を取得します。

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>();

次のステートメントはコンパイルエラーCannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree typeで失敗し、実行することさえできません

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

foreachを使用したこれは問題なく機能します。

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
    });
}

私がtopAgents.ToList()を同等に解釈できるようになった後、私の目では、コンパイラによってvar data = new List<List<object>>();の2番目のステートメントが許可されていると明示的に述べているからですか?

なぜコンパイラはLINQ selectを許可しないが、それぞれを許可するのですか?

58

問題は、topAgentsdynamicであるということです。したがって、ToList()呼び出しは動的であり、Selectも動的です。それには次の問題があります:

  1. このような動的呼び出しにラムダ式を使用することはできません。
  2. 動的呼び出しは、とにかく拡張メソッドを見つけません。

幸いなことに、elementタイプが動的であるという理由だけで、操作を動的にする必要はありません。次を使用できます。

IEnumerable<dynamic> topAgents = ...;

...またはvarを使用します。両方とも問題ないはずです。

82
Jon Skeet