2016-12-20 5 views
0

へのエンティティFramworkのメンバーを変更することはできません私は正常に動作私のアプリケーションでは、次のDbContextクラスを持っています。このアプローチはうまくいきますが、誰かが誤って私の基本コンテキストで顧客や連絡先に電話をかけることがあります。これは避けたいものです。が保護

私の理想的な解決策は、MyAppContextによってのみアクセスできるように、私のベースコンテキストのメンバーを保護することだと思っていましたが、データが2 DbSetにロードされていないので失敗します。例えば

public partial class BaseContext : DbContext 
{ 
    protected virtual DbSet<Customer> Customers { get; set; } 
    protected virtual DbSet<Contact> Contacts { get; set; } 
} 

私が保護にこれらを設定すると、彼らは公共everythigで結構です(これは私は避けたいこれら公にを公開)しているときに何もデータは、ロードされていません。

誰もこれに対処する方法について提案はありますか?

+1

これはEFが内部的に動作する方法と関係があると思います。アクセス修飾子に違反する外部からプロパティを伝播しようとします。 – Toxantron

+0

私はそれがオブジェクト上のプロパティで動作することを知っています。だから、 'DbSet'の' protected internal'を作るのはどうですか? – krillgar

+0

これは疑似カプセル化です。コンシューマーは常にcontext.Set ()にアクセスできます。また、ナビゲーションプロパティを使用して非アクティブな顧客を取得することはできません。ソフト削除には、より厳密なアプローチが必要です。 –

答えて

1

ソリューションは、あなたのベースクラスにDbSet<>プロパティを使用して、エンティティタイプを宣言する代わりに、流暢なAPIを使用しないことが考えられます。

public IQueryable<Customer> Customers => 
    Set<Customer>.Where(n => n.Active == true); 
public IQueryable<Contact> Contacts => 
    Set<Contact>.Where(n => n.Active == true); 
0

[自動プロパティ]ではなく、それらの実装を提供できます。

public partial class BaseContext : DbContext 
{ 
    protected virtual DbSet<Customer> Customers { get { return this.Set<Customer>(); } } 
    protected virtual DbSet<Contact> Contacts { get { return this.Set<Contact>(); } } 
} 
0

あなたは空のDbContextを使用して、このような一般的なリポジトリにそのインスタンスを渡すことができます。

public class GenericRepository<T> : IGenericRepository where T : class, new() 
{ 
    private readonly DbContext _context; 
    private readonly DbSet<T> _set; 

    public GenericRepository(DbContext context) 
    { 
     _context = _db; 
     _set = _context.Set<T>(); 
    } 

    public IQueryable<T> Query => _set.Where(m=>m.Active == true); 

    public virtual void Add(T entity) => _set.Add(entity); 

    public virtual void Update(T entity) => this._context.Entry(entity).State = EntityState.Modified; 

    public virtual void Delete(T entity) => _set.Remove(entity); 
} 

このパターンは、あなたのエンティティの動作を超えるくらいの細かい段階的に制御することができます。異なるクエリ/更新ロジックを使用して異なるリポジトリを実装することもできます。

public partial class BaseContext : DbContext 
{ 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Customer>(); 
     modelBuilder.Entity<Contact>(); 
    } 
} 

そしてMyAppContextに、あなたはあなたの特性をこのように宣言することができます。