В EF6, как создать универсальный метод для получения сущностей, используя общее поле/ столбец
-
20-12-2019 - |
Вопрос
извините, если название недостаточно поучительно, но через некоторое время я не смог придумать фразу, объясняющую мою проблему.
Это похоже на это:Я использую EF6, подход, основанный на базе данных.Все мои объекты имеют идентификатор и включенное свойство.У меня есть файл EDMX в моем DAL, и теперь мне нужно спроектировать бизнес-уровень (BLL для меня).
Поскольку мне нужно будет проверить, какие данные поступают из DAL и видны остальной части приложения, я решил создать интерфейс для общих операторов, создать базовый класс, который реализует это, и чтобы все мои пользовательские поставщики таблиц базы данных\сущностей наследовали это.
Если это не имеет смысла, вот что я делаю:(Все это есть в BLL)
public interface IEntityManager<T> where T : class {
void Add(T e, bool commit=false);
void Delete(T e);
void DeleteByID(int id);
void Update(T e);
IQueryable<T> Search(Expression<Func<T, bool>> predicate);
IQueryable<T> GetAll();
T Get(int id);
}
Итак, базовый класс, который реализует общие операции, - это:(отредактировано для удобства чтения и краткости)
public class EntityManager<TEntity> : IDisposable, IEntityManager<TEntity> where TEntity : class {
private readonly DbContext _ctx;
private readonly DbSet<TEntity> _set;
public EntityManager() {
_ctx = new DomainModelFactory();
_set = _ctx.Set<TEntity>();
}
public void Add(TEntity e) {
_set.AddOrUpdate(e);
}
//other methods here
public TEntity Get(int id) {
return _set.Find(id);
}
}
Чтобы создать менеджеров, которые действительно будут получать доступ к данным и использовать их в приложении, я планирую сделать что-то вроде:
public class VenueManager: EntityManager<Venue> {
public VenueManager():base() {
}
}
Для класса, который будет управлять моей сущностью Venue.Я создаю классы вместо того, чтобы использовать что-то вроде
var venueManager = new EntityManager<Venue>();
потому что у этих классов будут некоторые специализированные методы.Я надеюсь, вы смогли понять, что я сделал до сих пор (и это работает)
Теперь моя проблема в том, что у каждой сущности есть два общих поля:ID (int) и Enabled (bool) Я должен использовать их при удалении по id и при кодировании Get и GetAll, потому что я должен получать только те элементы, которые имеют Enabled=true.Теперь я знаю, что, поскольку я создаю классы менеджеров, я мог бы просто использовать c& p код, но мне было интересно, есть ли способ, которым я могу закодировать это в классе EntityManager и заставить всех менеджеров наследовать метод, но используя конкретные классы?
что-то вроде этого:В классе EntityManager:
public TEntity Get(int id) {
return _set.Where(T.ID==id);
}
В принципе, это то, чего я хочу:способ использовать эти свойства в базовом классе (EntityManager) там, где они важны (методы deletebyid, get и getall) таким образом, чтобы все классы менеджеров (ManagerVenue в примере) наследовали эти методы, чтобы мне не приходилось писать их снова и снова?(есть около 100 объектов)
Решение
Вы должны определить базовый класс или интерфейс для всех ваших сущностей, что-то вроде:
public class Entity {
public int Id { get; set; }
public bool Enabled { get; set; }
}
И в твоем EntityManager
класс добавляет общее ограничение к TEntity, например where TEntity : Entity
Тогда вы сможете использовать общие свойства Id
и Enabled
внутри вашего базового класса EntityManager
.