我已关注this tutorial并已在我的项目中实施。 我做了一些更改以使更多可测试,所以我实现了接口
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
internal MyEntities context;
internal IDbSet<T> dbSet;
public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
...
}
public interface IEmployeeRepository : IGenericRepository<Employee> { }
public class EmployeeRepository : GenericRepository<Employee>, IEmployeeRepository { }
UnitOfWork中的:
public class UnitOfWork : IDisposable
{
private MyEntities context = new MyEntities();
private IEmployeeRepository employeeRepository;
public IEmployeeRepository EmployeeRepository
{
get { return employeeRepository ?? (employeeRepository = new EmployeeRepository(context)); }
}
}
然后我无法访问GetWithRawSql()
中的dbSet,因为我更改为IDbSet
。
(1)如何解决这个问题?
(2)使用上述方法是否有更好的方法(没有dbSet),因为这也是失败的,因为IDbSet
unitOfWork.EmployeeRepository.dbSet.Select(c => new {
EmpID = c.EmployeeID,
FullName = (c.LastName + ", " + c.FirstName)
}).OrderBy(o => o.FullName);
感谢。
答案 0 :(得分:1)
我认为这是一个糟糕的实施,这是我目前使用的一个: 这将是你的IRepository
public interface IRepository<T> where T : class, IEntity
{
void Add(T item);
void Remove(T item);
void Update(T item);
void Attach(T item);
IQueryable<T> All<TProperty>(params Expression<Func<T, TProperty>>[] path);
IQueryable<T> All(params string[] path);
T Find(object id);
T First(Expression<Func<T, bool>> predicate, params string[] path);
Task<T> FirstAsync(Expression<Func<T, bool>> predicate, params string[] path);
T First<TProperty>(Expression<Func<T, bool>> predicate, params Expression<Func<T, TProperty>>[] path);
IQueryable<T> Where<TProperty>(Expression<Func<T, bool>> predicate, params Expression<Func<T, TProperty>>[] path);
IQueryable<T> Where(Expression<Func<T, bool>> predicate, params string[] includes);
}
通常你需要将实体附加到上下文中,所以我添加了Attach方法但是如果你想保持实体框架附加Seperate(并不是真的需要)来自常规IRepository你可以定义一个新的接口并调用ISqlRepository并从IRepository继承,创建两个IRepository会让它变得更加复杂,因为它会在UnitTest中产生任何问题。任何方式,如果你想分开这将是你的ISqlRespository:
public interface ISqlRepository<T>: IRepository<T> where T:class, IEntity
{
void Update(T item);
void Attach(T item);
}
这是unitOfWork接口:
public interface IUnitOfWork<T> where T : class, IEntity
{
IRepository<T> Repistory { get; }
IRepository<TEntity> GetTypeRepository<TEntity>() where TEntity : class, IEntity;
object GetContext();
int Commit();
Task<int> CommitAsync();
}
最后具体实现(没有ISqlRepository,因为我不使用它):
这是IRespository的实现:
public class SqlRepository<T>: IRepository<T> where T: class, IEntity
{
protected readonly DbSet<T> _objectSet;
protected ApplicationDbContext _context;
public SqlRepository(ApplicationDbContext context)
{
_objectSet = context.Set<T>();
this._context = context;
}
public void Add(T item)
{
_objectSet.Add(item);
}
public void Update(T item)
{
_context.Entry(item).State = EntityState.Modified;
}
public void Remove(T item)
{
_objectSet.Remove(item);
}
public T First(Expression<Func<T, bool>> predicate, params string[] path)
{
IQueryable<T> query = _objectSet;
if (path != null)
{
path.ForeEach(i => query = query.Include(i));
}
return query.FirstOrDefault(predicate);
}
public T First<TProperty>(Expression<Func<T, bool>> predicate, params Expression<Func<T, TProperty>>[] path)
{
IQueryable<T> query = _objectSet;
path.ForeEach(p => query = query.Include(p));
return query.First(predicate);
}
public IQueryable<T> Where<TProperty>(Expression<Func<T, bool>> predicate, params Expression<Func<T, TProperty>>[] path)
{
IQueryable<T> query = _objectSet;
path.ForeEach(p => query = query.Include(p));
return query.Where(predicate);
}
public IQueryable<T> Where(Expression<Func<T, bool>> predicate, params string[] includes)
{
IQueryable<T> query = _objectSet;
includes.ForeEach(i => query = query.Include(i));
return query.Where(predicate);
}
public IQueryable<T> All<TProperty>(params Expression<Func<T, TProperty>>[] path)
{
IQueryable<T> query = _objectSet;
if (path != null)
{
path.ForeEach(p => query.Include(p));
}
return query;
}
public IQueryable<T> All(params string[] path)
{
IQueryable<T> query = _objectSet;
if (path != null)
{
path.ForeEach(p => query = query.Include(p));
}
return query;
}
public T Find(object id)
{
return _objectSet.Find(id);
}
public void Attach(T item)
{
T old = _objectSet.Local.FirstOrDefault(i => i.Id == item.Id);
if (old != null)
{
_context.Entry<T>(old).State = EntityState.Detached;
}
_objectSet.Attach(item);
}
public System.Threading.Tasks.Task<T> FirstAsync(Expression<Func<T, bool>> predicate, params string[] path)
{
IQueryable<T> query = _objectSet;
if(path != null)
{
path.ForeEach(i => query = query.Include(i));
}
return query.FirstOrDefaultAsync(predicate);
}
}
这个单位工作:
public class SqlUnitOfWork<T> : IUnitOfWork<T> where T : class, IEntity
{
private ApplicationDbContext _db;
public SqlUnitOfWork(ApplicationDbContext context)
{
_db = context;
}
public IRepository<T> Repistory
{
get
{
return new SqlRepository<T>(_db);
}
}
public int Commit()
{
return _db.SaveChanges();
}
public Task<int> CommitAsync()
{
return _db.SaveChangesAsync();
}
public object GetContext()
{
return this._db;
}
public IRepository<TEntity> GetTypeRepository<TEntity>() where TEntity : class, IEntity
{
return new SqlRepository<TEntity>(_db);
}
}