В проекте используется общий репозиторий и общий менеджер, поэтому нам не нужно переписывать каждый метод 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. Это позволит нам избежать приведения в действие и позволить нам ограничивать, с каким типом мы можем манипулировать, используя один менеджер/репозиторий.
Есть ли у вас какие-либо идеи, как я мог бы это сделать?
Вы уже должны иметь возможность использовать конкретные типы без изменения общей реализации репозитория, это точка общих данных. Я думаю, что вы решили сопоставить несколько типов объектов с одной таблицей, зависит от того, как вы настроили свою модель. Вы могли бы использовать комбинацию представлений и хранимых процедур в своей модели, чтобы это произошло. – mclark1129