私はこの例外を取得しています:
指定されたタイプメンバー「有料」は、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);
}
エンティティは、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サーバーでフィルタリングする場合は、テーブルに計算列を作成するか、ストアドプロシージャを使用できます。
同様の問題を解決する必要がありました。上記のソリューションではメモリ内処理が必要であり、これは悪い習慣です(遅延読み込み)。
私の解決策は、述語を返すヘルパーを書くことでした:
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)を再利用する場合に便利です。欠点は、ロジックがドメインモデルにないことです。
LinqはステートメントをSQLステートメントに変換し、データベースに実行します。
現在、この変換は、エンティティメンバー、初期化子、およびエンティティナビゲーションプロパティに対してのみ発生します。そのため、関数を実行するか、プロパティの比較を取得するには、まずそれらをメモリ内のリストに変換し、関数を適用してデータを取得する必要があります。
したがって、全体として、
var debts = storeDB.Orders.toList()
.Where(o => o.Paid == false)
.OrderByDescending(o => o.DateCreated);
この問題は、DBモデルとビューモデルで同じ名前を持つ[NotMapped]
プロパティからも発生する可能性があります。
AutoMapperは、投影中にDBから選択しようとします。また、NotMappedプロパティは明らかにDBに存在しません。
解決策は、DBモデルからビューモデルにマッピングするときにAutoMapper構成のプロパティをIgnore
することです。
Foo
という名前の[NotMapped]
プロパティを探します。Foo
を持つプロパティを探します。.ForMember(a => a.Foo, b => b.Ignore());
を追加もう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時間以上を失う愚かなことです。
この状況は、EntityFrameworkタイプでサポートされていない(unsigned intなど)を使用している場合にも発生する可能性があります。
これはそのようなエラーの私の場合でした。
サポートされているタイプの詳細情報を確認してください: https://msdn.Microsoft.com/en-us/library/ee382832(v = vs.100).aspx
GFoley83で説明されている、このような状況に対するいくつかの回避策があります。 Entity Frameworkでunsigned int/long型を使用する方法?
get
without set
プロパティのみを持つメンバー変数があったため、この問題に直面しました
つまり、auto calculated
の列としてのnot stored
およびthe table
を意味します
したがって、not exist
のtable schema
make sure
のメンバー変数not auto calculated
がhave
agetter
およびsetter
プロパティに