我知道拥有一个“工作单元(Unit of Work)”就是在一个抽象层之上再加一个抽象层(即“DbContext”),这肯定是反模式,或者至少是不必要的。
我的问题如下:
我有一个通用的“IRepository”,例如:
这是该接口的实现:
我有一个名为 Facade 的项目,它实例化了一个 Mapper 和一个 UnitOfWork,如下所示:
现在让我们再次看一下Facade中的
如果我想要急加载MuscleType,我该如何更改Get()以接收Func的Expression而不是字符串?
我的问题如下:
我有一个通用的“IRepository”,例如:
public interface IGenericRepository<TEntity> where TEntity : class
{
IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "");
TEntity GetByID(object id);
void Insert(TEntity entity);
void Delete(object id);
void Delete(TEntity entityToDelete);
void Update(TEntity entityToUpdate);
}
这是该接口的实现:
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
internal GymHelperContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(GymHelperContext context)
{
this.context = context;
dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State == EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
我有一个名为 Facade 的项目,它实例化了一个 Mapper 和一个 UnitOfWork,如下所示:
public class MuscleFacade
{
private readonly UnitOfWork _unitOfWork = new UnitOfWork();
private readonly MuscleMapping _muscleMapping = new MuscleMapping();
public MuscleFacade()
{
}
public IEnumerable<MuscleViewModel> GetAllMuscles()
{
var source = _unitOfWork.MuscleRepository
.Get()
.ToList();
var result = source.Select(x => _muscleMapping.MuscleToModel(x));
return result;
}
public GymViewModel GetGymViewModel()
{
GymViewModel gymViewModel = new GymViewModel
{
ListOfMuscles = GetAllMuscles().ToList()
};
return gymViewModel;
}
}
MuscleFacade
类是我在控制器中使用Autofac注入的内容,我在其构造函数中注入了IMuscleFacade
。
现在问题是,我的MuscleTypeViewModel
有一个MuscleViewModel
列表,这些模型与其域类对应的模型进行映射,在这种情况下,MuscleType
有许多Muscle
(例如:Arm有bicep、tricep等),因此我在每个模型上都放置了导航属性,如下所示:
public class MuscleType : IEntity
{
public int Id { get; set; }
[StringLength(100)]
public string MuscleTypeName { get; set; }
public ICollection<Muscle> Muscles { get; set; }
}
public class Muscle : IEntity
{
public int Id { get; set; }
[StringLength(100)]
public string MuscleName { get; set; }
public int MuscleTypeId { get; set; }
public MuscleType MuscleType { get; set; }
}
现在让我们再次看一下Facade中的
GetAllMuscles
方法:public IEnumerable<MuscleViewModel> GetAllMuscles()
{
var source = _unitOfWork.MuscleRepository
.Get()
.ToList();
var result = source.Select(x => _muscleMapping.MuscleToModel(x));
return result;
}
如果我想要急加载MuscleType,我该如何更改Get()以接收Func的Expression而不是字符串?
nameof
运算符的引入减轻了表达式为基础的包含机制的需求。在nameof
之前,字符串版本对于代码维护来说是很糟糕的。 - grek40