1

次のコードは実行時エラーを生成していますが、その理由がわかりません。

from o in Orders
group o by o.Employee into employeeOrders
select new {
    employeeOrders.Key.EmployeeID,
    employeeOrders.Key.FirstName,
    Orders = 
        from eord in employeeOrders
        orderby eord.OrderID
        select new {
            eord.OrderID,
            eord.OrderDate,
            OrderTotal=eord.OrderDetails.Sum (od => od.UnitPrice)
        }
}

エラーは

「LINQPad.User.OrderDetails」のメンバーアクセス「System.Decimal UnitPrice」は、タイプ「LINQPad.User.Orders」では無効です

標準のドラッグ アンド ドロップ データ コンテキストと同じことを使用して、VS2010 でもこれを試しました。

前もって感謝します

4

1 に答える 1

0

現時点では完全に説明することはできません (デバッガーから必要な情報が得られません) EntitySet<OrderDetail>。のOrderDetailプロパティOrdersは読み込まれていないため (EntitySet は遅延読み込みに使用されるため)、アクセスできません。

let は EntitySet を直接呼び出すようになり、クエリが可能になりました。これは、H. Holterman のコメントとも一緒です。

もっと洗練された説明を見つけようとします。

編集

両者の違いは次のとおりです。

させて

    .Call System.Linq.Enumerable.Sum(
        ($<>h__TransparentIdentifier0.eord).Order_Details,
        .Lambda #Lambda6<System.Func`2[northwindtest.Order_Detail,System.Decimal]>))

(Lambda6 は Sum のラムダ、$<>h__TransparentIdentifier0.eord は let で定義された変数です)

せずに

    .Call System.Linq.Enumerable.Sum(
        $eord.Order_Details,
        .Lambda #Lambda5<System.Func`2[northwindtest.Order_Detail,System.Decimal]>))

あくまでも解釈ですのでご了承ください。let は、サブクエリEntitySetをデータで満たすことによって評価します (-> 遅延読み込み)。これにより、let で宣言された変数の外部でもデータを使用できるようになります (これも遅延読み込みです)。EntitySet<OrderDetail>式ツリーのさまざまな段階での状態を取得できないように見えるため、これがこのように機能する理由がわかりません。

System.Data.Linq.SqlClient.SqlMember.Expression.Set のこのコードによって例外が発生します。

if (!this.member.ReflectedType.IsAssignableFrom(value.ClrType) && !value.ClrType.IsAssignableFrom(this.member.ReflectedType))
{
    throw Error.MemberAccessIllegal(this.member, this.member.ReflectedType, value.ClrType);
}

Expression Translates の長い行の後。そのことから、ある種のサブクエリなしで式ツリーをSQLにレンダリングすることは不可能であるという結論を導き出します。なぜそれを自分でやらないのですか?私は見当もつかない。それが本当の理由であるかどうかはよくわかりません.MSの誰かに、より明確な(そしておそらく正しいウィンク)説明を求めてください.

少しでもお役に立てれば幸いです。フェマ

于 2010-05-02T21:32:41.790 に答える