在我的项目中,我不使用物理删除,我只是对所有表使用逻辑“软删除”。
我对所有查询使用此子句:
.Where(row => row.IsDeleted == false)
我希望避免在所有查询中重复此where
子句。
我有这样的方法来获取数据:
public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
{
return base.Set<TEntity>();
}
我称之为:
_categories = _uow.Set<Category>();
我该怎么做?
第一个想法:
添加一个基类并在其中放入Deleted
列并继承此基类中的所有类。这是一个好方法吗?
我使用UnitOfWork
和代码优先。
答案 0 :(得分:2)
public class GenericRepository<TEntity> where TEntity : class
{
internal MyContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(MyContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IQueryable<TEntity> GetNonDeleted(Expression<Func<TEntity, bool>> filter = null)
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
query = query.Where(row => row.IsDeleted == false);
return query;
}
// Other methods
}
答案 1 :(得分:2)
我不会仅为了重用单个属性而创建基类。相反,我会创建一个interfase和一个扩展方法来封装和重用where
语句。如下所示:
public static class EntityFrameworkExtentions
{
public static ObservableCollection<TEntity> Alive<TEntity>(this DbSet<TEntity> set)
where TEntity : class, ISoftDeleteAware
{
var data = set.Where(e => e.IsDeleted == false);
return new ObservableCollection<TEntity>(data);
}
}
接口声明
public interface ISoftDeleteAware
{
bool IsDeleted { get;set;}
}
用法:
var coll = DbContext.Categories.Alive();
答案 2 :(得分:1)
如果你从不删除任何东西,那么你可以使用它的基本实体类和IsDelete属性。之后,将此基本实体用于Generic Repository。它看起来像;
public abstract class BaseModel
{
public BaseModel()
{
IsDelete = false;
CreateDate = DateTime.Now;
}
[Key]
public int Id { get; set; }
public bool IsDelete{ get; set; }
public virtual DateTime CreateDate { get; set; }
public virtual DateTime UpdateDate { get; set; }
}
public class YourClassHere : BaseModel
{
//
}
public class Repository<T> : IRepository<T> where T : BaseModel
{
private readonly IDbContext _context;
private IDbSet<T> _entities;
public Repository(IDbContext context)
{
this._context = context;
}
public T GetByIdByIgnoringDeleteStatus(int id)
{
return this.Entities.Find(id);
}
public T GetById(int id)
{
return this.Entities.Single(item => item.Id == id && !item.IsDelete);
}
public void Create(T entity)
{
try
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
entity.CreateDate = DateTime.Now;
this.Entities.Add(entity);
//this._context.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
var msg = string.Empty;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
msg += string.Format("Property: {0} Error: {1}",
validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine;
}
}
var fail = new Exception(msg, dbEx);
throw fail;
}
}
public void Update(T entity)
{
try
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
entity.UpdateDate = DateTime.Now;
this._context.SetModified(entity);
//this._context.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
var msg = string.Empty;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
msg += Environment.NewLine + string.Format("Property: {0} Error: {1}",
validationError.PropertyName, validationError.ErrorMessage);
}
}
var fail = new Exception(msg, dbEx);
throw fail;
}
}
public void Delete(T entity)
{
try
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
entity.UpdateDate = DateTime.Now;
this.Entities.Remove(entity);
//this._context.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
var msg = string.Empty;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
msg += Environment.NewLine + string.Format("Property: {0} Error: {1}",
validationError.PropertyName, validationError.ErrorMessage);
}
}
var fail = new Exception(msg, dbEx);
throw fail;
}
}
public virtual IQueryable<T> GetAll()
{
return this.Entities;
}
private IDbSet<T> Entities
{
get
{
if (_entities == null)
{
_entities = _context.Set<T>();
}
return _entities;
}
}
}
现在,您可以将类方法与删除状态一起使用。