2012-04-10 12 views
1

プロジェクトでは、ジェネリック・リポジトリおよびジェネリック・マネージャを使用しているため、すべてのリポジトリ/マネージャのすべての更新/削除メソッドを書き換える必要はありません。ここでエンティティ・フレームワーク、抽象クラス、ジェネリック・リポジトリおよびジェネリック・マネージャ

は、彼らがどのように見えるかです:

public interface IBaseRep<T> : IDisposable where T : class, PrivateObject 
{ 
    DbSet<T> DatabaseSet { get; set; } 
    DbContext Dal { get; set; } 

    T Find(int? id); 
    T Find(Expression<Func<T, bool>> predicate); 
    ICollection<T> Select(Expression<Func<T, bool>> predicate = null, 
     Expression<Func<T, string>> orderBy = null, 
     string includeProperties = ""); 
    T Create(T obj); 
    T Update(T obj); 
    bool Delete(T obj); 
    bool Delete(int id); 
    bool Delete(Expression<Func<T, bool>> predicate); 
    IQueryable<T> SelectAsQuery(
     Expression<Func<T, bool>> predicate = null, 
     Expression<Func<T, string>> orderBy = null, 
     string includeProperties = ""); 
} 

public class BaseRep<T> : IBaseRep<T> where T : class, PrivateObject 
{ 
    public DbSet<T> DatabaseSet { get; set; } 
    public DbContext Dal { get; set; } 

    public EORTCBaseRep(DbContext dal) 
    { 
     this.Dal = dal; 
     this.DatabaseSet = Dal.Set<T>(); 
    } 

    public virtual T Find(int? id) 
    { 
     return this.DatabaseSet.Find(id); 
    } 

    public virtual T Find(Expression<Func<T, bool>> predicate) 
    { 
     return Select(predicate).FirstOrDefault(); 
    } 

    public virtual ICollection<T> Select(
     Expression<Func<T, bool>> predicate = null, 
     Expression<Func<T, string>> orderBy = null, 
     string includeProperties = "") 
    { 
     return SelectAsQuery(predicate, orderBy, includeProperties).ToList(); 
    } 

    public virtual IQueryable<T> SelectAsQuery(
     Expression<Func<T, bool>> predicate = null, 
     Expression<Func<T, string>> orderBy = null, 
     string includeProperties = "") 
    { 
     IQueryable<T> query = this.DatabaseSet; 

     if (predicate != null) 
      query = query.Where(predicate); 

     foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) 
      query = query.Include(includeProperty); 

     if (orderBy != null) 
      query = query.OrderBy(orderBy); 

     return query; 
    } 

    public virtual T Create(T obj) 
    { 
     this.Dal.Entry<T>(obj).State = EntityState.Added; 
     this.Dal.SaveChanges(); 
     return obj; 
    } 

    public virtual T Update(T obj) 
    { 
     this.Dal.Entry<T>(obj).State = EntityState.Modified; 
     this.Dal.SaveChanges(); 
     return obj; 
    } 

    public virtual bool Delete(T obj) 
    { 
     if (obj is ILogicallyDeletable) 
     { 
      this.Dal.Entry<T>(obj).State = EntityState.Modified; 
      (obj as ILogicallyDeletable).IsDeleted = true; 
     } 
     else 
     { 
      this.Dal.Entry<T>(obj).State = EntityState.Deleted; 
     } 
     return this.Dal.SaveChanges() == 1; 
    } 

    public virtual bool Delete(int id) 
    { 
     T obj = Find(id); 
     return Delete(obj); 
    } 

    public virtual bool Delete(Expression<Func<T, bool>> predicate) 
    { 
     foreach (T item in Select(predicate)) 
     { 
      Delete(item); 
     } 
     return this.Dal.SaveChanges() == 1; 
    } 

    public virtual void Dispose() 
    { 
     this.Dal.Dispose(); 
    } 
} 

当社の経営者は、次のようになります。

public interface IBaseManager<T> : IDisposable where T : class, PrivateObject 
{ 
    T Find(int? id); 
    T Find(Expression<Func<T, bool>> predicate); 
    ICollection<T> Select(Expression<Func<T, bool>> predicate = null, 
     Expression<Func<T, string>> orderBy = null, 
     string includeProperties = ""); 
    T Create(T obj); 
    T Update(T obj); 
    bool Delete(T obj); 
    bool Delete(int id); 
    bool Delete(Expression<Func<T, bool>> predicate); 
    IQueryable<T> SelectAsQuery(
     Expression<Func<T, bool>> predicate = null, 
     Expression<Func<T, string>> orderBy = null, 
     string includeProperties = ""); 
} 

public class BaseManager<T> : IBaseManager<T> where T : class, PrivateObject 
{ 
    protected IBaseRep<T> Repository; 

    public virtual T Find(int? id) 
    { 
     return this.Repository.Find(id); 
    } 

    public virtual T Find(Expression<Func<T, bool>> predicate) 
    { 
     return this.Repository.Find(predicate); 
    } 

    public virtual ICollection<T> Select(
     Expression<Func<T, bool>> predicate = null, 
     Expression<Func<T, string>> orderBy = null, 
     string includeProperties = "") 
    { 
     return this.Repository.Select(predicate, orderBy, includeProperties); 
    } 

    public virtual IQueryable<T> SelectAsQuery(
     Expression<Func<T, bool>> predicate = null, 
     Expression<Func<T, string>> orderBy = null, 
     string includeProperties = "") 
    { 
     return this.Repository.SelectAsQuery(predicate, orderBy, includeProperties); 
    } 

    public virtual T Create(T obj) 
    { 
     return this.Repository.Create(obj); 
    } 

    public virtual T Update(T obj) 
    { 
     return this.Repository.Update(obj); 
    } 

    public virtual bool Delete(T obj) 
    { 
     return this.Repository.Delete(obj); 
    } 

    public virtual bool Delete(int id) 
    { 
     return this.Repository.Delete(id); 
    } 

    public virtual bool Delete(Expression<Func<T, bool>> predicate) 
    { 
     return this.Repository.Delete(predicate); 
    } 

    public virtual void Dispose() 
    { 
     if (this.Repository != null) 
      this.Repository.Dispose(); 
    } 
} 

これはうまく動作します。

しかし、我々は今、複数のエンティティタイプに同じDBテーブルを使用する必要があります。

public abstract class AbstractSite : PrivateObject, IActivable, ILogicallyDeletable 
{ 
    public int Id { get; set; } 
} 

public class EthicCommittee : AbstractSite 
{ 
    public int Number { get; set; } 
} 

public class Site : AbstractSite 
{ 
    public string Name { get; set; } 
} 

これは、我々は一般的なマネージャーを使用する方法である:

public class AbstractSiteManager : BaseManager<AbstractSite> 
{ 
    public AbstractSiteManager (PrismaDAL prismaDAL = null) 
    { 
     this.Repository = new AbstractSiteRep(prismaDAL); 
    } 
} 

とどのように我々は一般的なリポジトリを使用します:

public class AbstractSiteRep : PrismaBaseRep<AbstractSite> 
{ 
    public AbstractSiteRep (PrismaDAL prismaDAL = null) 
     : base(prismaDAL) 
    {} 
} 

public class PrismaBaseRep<T> : BaseRep<T> where T : class, PrivateObject 
{ 
    public PrismaBaseRep(PrismaDAL prismaDAL = null) : base((prismaDAL == null) ? new PrismaDAL() : prismaDAL) 
    { } 
} 

しかし、ここでは抽象型のanymorではなくconcrete型を使用したいと思いますe(AbstractSite = abstract; Site = concrete、RecruitingInstitution = concrete ...)を使用して、汎用リポジトリ/マネージャに触れないでください。だから私たちはXの汎用リポジトリを持っています(X:具体的な型の数)。それらのすべてが同じDB表を指しています。 これにより、キャストを回避し、1つのマネージャ/リポジトリを使用して操作できるタイプを制限することができます。

私はこれをどのように達成できるか考えていますか?

+0

ジェネリックリポジトリの実装を変更せずに具体的な型を使用することができるはずです。これがジェネリックのポイントです。複数のエンティティタイプを1つのテーブルにマップする方法は、モデルの設定方法によって異なります。これを実現するには、モデルにビューとストアドプロシージャの組み合わせを使用することもできます。 – mclark1129

答えて

1

解決済み 私の間違い。

これは@Mike Cと同じようにうまく動作します。

抽象的な(TPHの)代わりに具体的なオブジェクト型を参照していた場合、EFが正しい表を見つけることができなかっただけです。

関連する問題