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


102

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

指定された型のメンバー '有料'は、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);
        }
    }

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

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

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

        return View(debts);
    }

15
簡単な答え:マップされていないプロパティをlinq-to-entitiesクエリで使用することはできません!マップされたプロパティのみがSQLに変換されます。
Ladislav Mrnka、2011

回答:


114

エンティティは有料プロパティを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サーバーでフィルタリングする場合は、テーブルに計算列を作成するか、ストアドプロシージャを使用できます。


25

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

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

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)を再利用する場合に便利です。欠点は、ロジックがドメインモデルにないことです。


1
このアプローチを「組み込み」にするライブラリーは多数あります。stackoverflow.com/ a / 27383641/470183を参照してください。Linq-to-entitiesは、SQLに変換できる「正規関数」を使用する式に制限されています。C#6は「式のボディ関数」を導入しましたが、これらは本当のラムダではありません(stackoverflow.com/a/28411444/470183を参照)。それでもフレームワークでこれを使用するのは良いことなので、WIBNIdata.uservoice.com /
James Close

1
このシンプルで簡潔な例をありがとうございますExpression<Func<xx,yy>>。私は以前にそれを理解したことがありましたが、今では明白に見えます。
AlexB 2016

17

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

AutoMapperは、プロジェクション中にDBからそれを選択しようとします。NotMappedプロパティは明らかにDBに存在しません。

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

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

Dang AutoMapper Projectionも私を捕まえました、答えてくれてありがとう!
チェイスフロレル2018年

15

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

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

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

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

21
私はそれが全体のリストを取得する意味しますので、受注に)(ToListメソッドを作るために誰かを尋ねることは危険であることを示唆している
elgrego

私の問題のあるプロパティはWhere句ではなくSum Linq関数にあるため、これは私にとっては良いことです。だから私は不必要なデータを取得しておらず、取得したデータでリストで動作しているLinq Sum関数を実行しています。ありがとうございました!最初は見栄えが悪いものは、特定の状況で非常に役立ちます。
Dov Miller

11

もう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時間かけて失う愚かなこと。


2

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

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

サポートされているタイプの詳細については、https//msdn.microsoft.com/en-us/library/ee382832(v = vs.100).aspxをご覧ください。

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


このリンクはかなりの時間を節約しました!本当にありがとうございました!
Vladimir Semashkin

0

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

そのそのの手段auto calculatednot stored列のようにthe table

したがって、そのnot existtable schema

そうmake sureその任意のメンバ変数not auto calculatedへと特性havegettersetter


-1

edmxとコンテキストモデルには、dbに新しく追加されたいくつかの異なるプロパティがあります。

EDMXを更新して適切に更新しますプロジェクトをBulidして、再度実行します。

それはあなたの問題を解決します。

よろしく、ガネーシュニカム

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.