2012-04-10 7 views
1

В проекте используется общий репозиторий и общий менеджер, поэтому нам не нужно переписывать каждый метод update/delete и т. Д. В каждом хранилище/менеджере.Структура Entity, абстрактный класс, общий репозиторий и общий менеджер

Вот как они выглядит:

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(); 
    } 
} 

Это хорошо работает.

Но теперь мы должны использовать ту же таблицу БДА для нескольких типов сущностей:

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 e (AbstractSite = abstract; Site = конкретный, RecruitingInstitution = конкретный ...), не касаясь общего репозитория/менеджера. Таким образом, у нас будет X общий репозиторий (где X: количество конкретных типов). Все они указывают на ту же таблицу DB. Это позволит нам избежать приведения в действие и позволить нам ограничивать, с каким типом мы можем манипулировать, используя один менеджер/репозиторий.

Есть ли у вас какие-либо идеи, как я мог бы это сделать?

+0

Вы уже должны иметь возможность использовать конкретные типы без изменения общей реализации репозитория, это точка общих данных. Я думаю, что вы решили сопоставить несколько типов объектов с одной таблицей, зависит от того, как вы настроили свою модель. Вы могли бы использовать комбинацию представлений и хранимых процедур в своей модели, чтобы это произошло. – mclark1129

ответ

1

Решено Моя ошибка.

Это прекрасно работает как @Mike C.

Я просто не знал, что EF смог найти правильную таблицу, если бы я ссылался на конкретный тип объекта вместо абстрактного (в TPH).

Смежные вопросы