Рассмотрим следующий код:
public abstract class RepositoryBase<T> where T : class
{
#region Members
private MyContext dataContext;
private readonly IDbSet<T> dbset;
#endregion
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get; private set;
}
protected MyContext DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
public virtual void Delete(T entity)
{
dbset.Remove(entity);
}
Я бы хотел заменить метод Delete на приведенный ниже, поскольку я бы предпочел просто установить для поля Deleted значение true в моем объекте, чтобы указать, что он удален, вместо того, чтобы действительно его удалять.
public virtual void Delete(T entity)
{
entity.Deleted = true;
dbset.Attach(entity);
dataContext.Entry(entity).State = EntityState.Modified;
}
Я использую объекты POCO, и свойство Deleted существует во всех из них. Однако в приведенном выше коде сущность имеет тип T, и T «не знает», что существует свойство Deleted во всех объектах, которые оно может представлять. Какой самый элегантный способ решить эту проблему?
Кстати, я хотел бы получить доступ к другим полям (DateCreated, CreatedBy, DateModified и ModifiedBy) аналогичным образом в моем абстрактном классе.
ОБНОВЛЕНИЕ : Я попробовал как интерфейс, так и решение класса Abstract, что сначала казалось хорошим, но затем я получил следующее сообщение об ошибке в обоих случаях при компиляции:
Ошибка 11 Тип «MyProject.Domain.Person» нельзя использовать в качестве параметра типа «T» в универсальном типе или методе «MyProject.Data.Infrastructure.RepositoryBase». Не существует неявного преобразования ссылок из MyProject.Domain.Person в MyProject.Domain.AbstractEntity.
А вот код, на который ссылается сообщение об ошибке:
namespace MyProject.Data
{
public class PersonRepository : RepositoryBase<Person>, IPersonRepository
{
public PersonRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
}
public interface IPersonRepository : IRepository<Person>
{
}
}
Обновление 2:
Я наконец-то заставил его работать с решением, предложенным SLaks. Я использовал интерфейс и изменил шаблон, генерирующий все объекты POCO, чтобы они все были получены из следующего интерфейса IEntity:
namespace MyProject.Domain
{
public interface IEntity
{
System.DateTime CreatedDate
{
get;
set;
}
string CreatedBy
{
get;
set;
}
System.DateTime ModifiedDate
{
get;
set;
}
string ModifiedBy
{
get;
set;
}
bool Deleted
{
get;
set;
}
}
}
Использование абстрактного класса сущностей было бы более сложным, поскольку тогда все свойства в абстрактном классе пришлось бы переопределять в классах сущностей.