web-dev-qa-db-ja.com

初期化子、エンティティメンバー、およびエンティティナビゲーションプロパティのみがサポートされます

私はこの例外を取得しています:

指定されたタイプメンバー「有料」は、LINQ to Entitiesではサポートされていません。初期化子、エンティティメンバー、およびエンティティナビゲーションプロパティのみがサポートされています。

    public ActionResult Index()
    {
        var debts = storeDB.Orders
            .Where(o => o.Paid == false)
            .OrderByDescending(o => o.DateCreated);

        return View(debts);
    }

私のモデルクラス

public partial class Order
{
    public bool Paid {
        get {
            return TotalPaid >= Total;
        }
    }

    public decimal TotalPaid {
        get {
            return Payments.Sum(p => p.Amount);
        }
    }

支払いはフィールドの金額を含む関連テーブルです。支払いに関する正しい情報を示すWhere句を削除すると、クエリは機能します。コードの何が問題なのでしょうか?

:で提案された答えのように解かれました

    public ActionResult Index()
    {
        var debts = storeDB.Orders
            .OrderByDescending(o => o.DateCreated)
            .ToList()
            .Where(o => o.Paid == false);

        return View(debts);
    }
97
Marc

エンティティは、PaidプロパティをSQLに変換しようとしていますが、テーブルスキーマの一部ではないためできません。

あなたができることは、エンティティに有料フィルタなしでテーブルを照会させ、その後、有料のものを除外することです。

public ActionResult Index()
{
    var debts = storeDB.Orders
        //.Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);

    debts = debts.Where(o => o.Paid == false);

    return View(debts);
}

それはもちろん、すべてのデータをWebサーバーに戻し、そのデータをフィルタリングすることを意味します。 DBサーバーでフィルタリングする場合は、テーブルに計算列を作成するか、ストアドプロシージャを使用できます。

110
Eugene S.

同様の問題を解決する必要がありました。上記のソリューションではメモリ内処理が必要であり、これは悪い習慣です(遅延読み込み)。

私の解決策は、述語を返すヘルパーを書くことでした:

public static class Extensions
{
    public static Expression<Func<Order, bool>> IsPaid()
    {
        return order => order.Payments.Sum(p => p.Amount) >= order.Total;
    }
}

Linqステートメントを次のように書き換えることができます。

var debts = storeDB.Orders
                    .Where(Extensions.IsPaid())
                    .OrderByDescending(o => o.DateCreated);

これは、計算ロジック(DRY)を再利用する場合に便利です。欠点は、ロジックがドメインモデルにないことです。

23
Koen Luyten

LinqはステートメントをSQLステートメントに変換し、データベースに実行します。

現在、この変換は、エンティティメンバー、初期化子、およびエンティティナビゲーションプロパティに対してのみ発生します。そのため、関数を実行するか、プロパティの比較を取得するには、まずそれらをメモリ内のリストに変換し、関数を適用してデータを取得する必要があります。

したがって、全体として、

var debts = storeDB.Orders.toList()
        .Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);
15
T Gupta

この問題は、DBモデルとビューモデルで同じ名前を持つ[NotMapped]プロパティからも発生する可能性があります。

AutoMapperは、投影中にDBから選択しようとします。また、NotMappedプロパティは明らかにDBに存在しません。

解決策は、DBモデルからビューモデルにマッピングするときにAutoMapper構成のプロパティをIgnoreすることです。

  1. DBモデルでFooという名前の[NotMapped]プロパティを探します。
  2. ビューモデルで同じ名前Fooを持つプロパティを探します。
  3. その場合は、AutoMapperの設定を変更してください。 .ForMember(a => a.Foo, b => b.Ignore());を追加
15
Jess

もう1つの考えられる理由は、プロパティにIEnumerableではなくICollectionを使用しているためです。

代わりに:

public class This
{
    public long Id { get; set; }
    //...
    public virtual IEnumerable<That> Thats { get; set; }
}

これを行う:

public class This
{
    public long Id { get; set; }
    //...
    public virtual ICollection<That> Thats { get; set; }
}

そして、あなたは気難しいドーリー... 2時間以上を失う愚かなことです。

11
Serj Sagan

この状況は、EntityFrameworkタイプでサポートされていない(unsigned intなど)を使用している場合にも発生する可能性があります。

これはそのようなエラーの私の場合でした。

サポートされているタイプの詳細情報を確認してください: https://msdn.Microsoft.com/en-us/library/ee382832(v = vs.100).aspx

GFoley83で説明されている、このような状況に対するいくつかの回避策があります。 Entity Frameworkでunsigned int/long型を使用する方法?

2
Ony

getwithout setプロパティのみを持つメンバー変数があったため、この問題に直面しました

つまり、auto calculatedの列としてのnot storedおよびthe tableを意味します

したがって、not existtable schema

make sureのメンバー変数not auto calculatedhave a getterおよびsetterプロパティに

0