2016-05-12 9 views
0

関連する子エンティティをフィルタで一般的に読み込む関数を作成しようとしています。Entity Framework、where条件付きの関連エンティティの一般的なロード

すべての私のエンティティは、自分自身の基本クラスIが供給されると、エンティティが関連するすべての子オブジェクトをロードすることを次の関数を作成している

public abstract class BusinessObject : BaseObject, IBaseObject, ILocalObject 
{ 
    [Browsable(false)] 
    [Key] 
    public int ID { get; set; } 

    [Browsable(false)] 
    public int? HqID { get; set; } 

    private bool _deleted; 
    [Browsable(false)] 
    public bool Deleted 
    { 
     get { return _deleted; } 
     set { CheckPropertyChanged(ref _deleted, value); } 
    } 
} 

「てBusinessObject」に由来しています。 エンティティを定義するとき、すべての子コレクションは自分自身の属性 "EntityChildCollectionAttribute"でフラグが立てられているので、ロードしたいコレクションを簡単に見つけることができます。

public virtual void OnLoadEntityChildren(object entity) 
    { 
     var propNames = entity.GetPropertyNames(); 
     foreach (var propName in propNames.Where(propName => entity.PropertyHasCustomAttribute(propName, typeof(EntityChildCollectionAttribute)))) 
     { 
      MyData.Entry(entity).Collection(propName).Load();        
     } 
    } 

これは素敵です! 子コレクションをフィルタリングするときに問題が発生します。

この場合、削除済み== falseの子エンティティのみをロードします。

私はこれを行う方法をうまくいかない!

私はMyData.Entry(エンティティ).Collection(propName).Load();

MyData.Entry(entity).Collection(propName).Query().Cast<BusinessObject>().Where(x=>x.Deleted.Equals(false)).Load(); 

とコンパイルしますが、エラーが発生します。

"'FmOrderProcessing.Entities.OpDocumentDetail'を 'FwBaseEntityFramework.BusinessObject'と入力するとキャストできませんLINQ to EntitiesはEDMプリミティブまたは列挙型のキャストのみサポートしています。

どれヘルプ/ポインタ/回答は感謝して、私が削除されたように、データベース内のレコードにフラグが設定されることを意味し、「ソフト削除」パターンを実装して、事前に

おかげ

ランス

+0

は時々ちょうどSPROCを書き、....純粋なSQLは最良の答えで書き込みができます願っています。 –

+0

EFは 'BusinessObject'を知らない。マップされたタイプではありません。 –

+0

ところで、なぜあなたが 'Include'を使わないのか不思議です。あなたのコードは、各親の子コレクションを別々に読み込みます。これは、n + 1のアンチパターンとも呼ばれます。 –

答えて

2

を受信します削除されるのではなく(監査と複製の目的で)削除されます。

すべてのエンティティは、bool Deletedプロパティを持つ基本定義から派生しています。

私はここで答えを見つけました:

https://www.nuget.org/packages/EntityFramework.DynamicFilters

をこのパッケージには、データのコンテキストでグローバルフィルタを定義できます。 OnModelCreatingオーバーライドの1行のコードで問題を修正しました。

modelBuilder.Filter("Deleted", (IBaseObject d) =>d.Deleted, false); 

フィルタ機能は、(私の場合は)IBaseObjectインターフェイスを提示するすべてのエンティティにグローバルに適用されます。

私は、これはそれがEFで複雑すぎるなってきた場合は、同様の問題を持つ他のすべてのボディ

関連する問題