我有一个Windows Forms应用程序和通用的Entity Framework(最新版本)方法以及多层设计模式。
我要加载特定列,而不是所有列。
例如,我有10列(a1 ... a10),但是我只想从(a1 ... a8)列中获取数据。这是我获取所有列的代码-我该怎么办?
存储层:
public Repository(GlobalERPEntities context)
{
Context = context;
dbSet = Context.Set<T>();
}
public virtual IEnumerable<T> GetAll()
{
return dbSet.ToList();
}
UnitOfWork层:调用从存储库层获取所有方法
public UnitOfWork()
{
Context = new GlobalERPEntities();
}
public Repository<T> Repository<T>() where T : class
{
if (repositories == null)
{
repositories = new Dictionary<Type, object>();
}
if (repositories.Keys.Contains(typeof(T)) == true)
{
return repositories[typeof(T)] as Repository<T>;
}
Repository<T> repo = new Repository<T>(Context);
repositories.Add(typeof(T), repo);
return repo;
}
BLL层:调用从UnitOfWork层获取所有方法
protected UnitOfWork uow;
public Service()
{
uow = new UnitOfWork();
}
public virtual IEnumerable<T> GetAll()
{
return uow.Repository<T>().GetAll().ToList();
}
如何更改它以获得一组自定义列,以及如何在我的表单中调用它?
答案 0 :(得分:2)
我为您提供了一个简单的解决方案,如下所示:首先如下编写IUnitOfWork
:
public interface IUnitOfWork
{
IRepository<T> Repository<T>() where T : class;
Task SaveChangesAsync();
void ResetContextState();
}
然后将UnitOfWork
类如下:
public class UnitOfWork : IUnitOfWork
{
private readonly YourDbContext _dbContext;
private Hashtable _repositories;
public UnitOfWork(YourDbContext dbContext)
{
_dbContext = dbContext;
}
public IRepository<T> Repository<T>() where T : class
{
if (_repositories == null)
_repositories = new Hashtable();
var type = typeof(T).Name;
if (!_repositories.ContainsKey(type))
{
var repositoryType = typeof(Repository<>);
var repositoryInstance =
Activator.CreateInstance(repositoryType
.MakeGenericType(typeof(T)), _dbContext);
_repositories.Add(type, repositoryInstance);
}
return (IRepository<T>)_repositories[type];
}
public async Task SaveChangesAsync()
{
await _dbContext.SaveChangesAsync();
}
public void ResetContextState()
{
_dbContext.ChangeTracker.Entries().Where(e => e.Entity != null).ToList()
.ForEach(e => e.State = EntityState.Detached);
}
}
现在编写IRepository
接口,如下所示:
public interface IRepository<TEntity> where TEntity : class
{
IQueryable<TEntity> GetEntities(Expression<Func<TEntity, bool>> condition = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "");
Task<bool> IsEntityExists(Expression<Func<TEntity, bool>> filter = null);
void InsertEntity(TEntity entity);
void InsertEntities(List<TEntity> entities);
void UpdateEntity(TEntity entity, params string[] excludeProperties);
void DeleteEntity(TEntity entity);
void DeleteEntities(List<TEntity> entities);
Task<bool> IsTableEmptyAsync();
}
然后按如下所示操作您的Repository
类:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
private readonly YourDbContext _dbContext;
private readonly DbSet<TEntity> _dbSet;
public Repository(YourDbContext dbContext)
{
_dbContext = dbContext;
_dbSet = _dbContext.Set<TEntity>();
}
public IQueryable<TEntity> GetEntities(Expression<Func<TEntity, bool>> condition = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = _dbSet;
if (condition != null)
{
query = query.Where(condition);
}
foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
query = orderBy(query);
}
return query;
}
public async Task<bool> IsEntityExists(Expression<Func<TEntity, bool>> condition)
{
bool status = false;
if (condition != null)
{
status = await _dbSet.AnyAsync(condition);
}
return status;
}
public void InsertEntity(TEntity entity)
{
_dbSet.Add(entity);
}
public void InsertEntities(List<TEntity> entities)
{
_dbSet.AddRange(entities);
}
public void UpdateEntity(TEntity entity, params string[] excludeProperties)
{
_dbContext.Entry(entity).State = EntityState.Modified;
foreach (string property in excludeProperties)
{
_dbContext.Entry(entity).Property(property).IsModified = false;
}
}
public void DeleteEntity(TEntity entity)
{
_dbSet.Remove(entity);
}
public void DeleteEntities(List<TEntity> entities)
{
_dbSet.RemoveRange(entities);
}
public async Task<bool> IsTableEmptyAsync()
{
bool hasAny = await _dbSet.AnyAsync();
return !hasAny;
}
}
然后在您的服务类或以下任何地方使用UnitOfWork
:
public class EmployeeService
{
private readonly UnitOfWork _unitOfWork;
public EmployeeService()
{
_unitOfWork = new UnitOfWork();
}
public List<Employee> GetAllEmployees()
{
return _unitOfWork.Repository<Employee>().GetEntities().ToList();
}
public List<string> GetAllEmployeeNames()
{
return _unitOfWork.Repository<Employee>().GetEntities().Select(emp => emp.Name).ToList();
}
}
最好与依赖项注入配合使用,如下所示:
public class EmployeeService
{
private readonly IUnitOfWork _unitOfWork;
public EmployeeService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public List<Employee> GetAllEmployees()
{
return _unitOfWork.Repository<Employee>().GetEntities().ToList();
}
public List<string> GetAllEmployeeNames()
{
return _unitOfWork.Repository<Employee>().GetEntities().Select(emp => emp.Name).ToList();
}
}
答案 1 :(得分:0)
当我使用 UnitOfWork 模式时,我遵循与 Microsoft 文档中指定的几乎相同的 template。
您可以按如下方式调整 Get
方法(或添加新方法)(注意我们用于指定列的附加 select
参数):
public virtual IEnumerable<TDest> Get<TDest>(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "",
Expression<Func<TEntity, TDest>> select = null)
{
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)
{
if (select == null)
return (IEnumerable<TDest>)orderBy(query).ToList();
return orderBy(query).Select(select).ToList();
}
else
{
if (select == null)
(IEnumerable<TDest>)query.ToList();
return query.Select(select).ToList();
}
}
示例使用
public class Cat
{
public string Name { get; set; }
public int Age { get; set; }
public string { get; set; }
}
// Select Name column only
var names = unitOfWork.CatRepository.Get(
null, // No filter
x => x.OrderByDescending(y => y.Age), // Order by oldest
string.Empty, // No includeProperties
x => x.Name // Select the Name column only
)
// Output: "Fluffy"
// Select Name and Age columns only
var namesAndAges = unitOfWork.CatRepository.Get(
x => x.Age > 1, // Where Age is greater than 1
null, // No order
string.Empty, // No includeProperties
x => new { Name = x.Name, Age = x.Age) // Select the Name and Age columns only
)
// Output: { Name = "Fluffy", Age = 3 }
// Select the entity (no columns specified)
var all = unitOfWork.CatRepository.Get<Cat>(
null, // No filter
null, // No order
string.Empty, // No includeProperties
null) // Select the Name and Age columns only
)
// Output: { Cat() { Name = "Fluffy", Age = 3, Breed = "Moggy" } }
// Same query as above
var allSimple = unitOfWork.CatRepository.Get<Cat>()
// Output: { Cat() { Name = "Fluffy", Age = 3, Breed = "Moggy" } }