在何处放置存储库的多个查询
本文关键字:查询 存储 在何处 | 更新日期: 2023-09-27 17:59:05
我不确定将业务对象的特定查询放在哪里。
当我们开始对存储库模式使用多个特定于表的查询时,其中这些应该放吗?服务层还是存储库?
例如,请参阅以下内容:
例如:
class HR_Repository<T> : IRepository<T> where T : class
{
private readonly LoginDataContext dataContext;
public HR_Repository(LoginDataContext dataContext)
{
this.dataContext = dataContext;
}
public void Commit()
{
dataContext.SubmitChanges();
}
public IList<T> FindAll()
{
var table = this.LookupTableFor(typeof(T));
return table.Cast<T>().ToList();
}
public IQueryable<T> Find()
{
var table = this.LookupTableFor(typeof(T));
return table.Cast<T>();
}
public void Add(T item)
{
var table = this.LookupTableFor(typeof(T));
table.InsertOnSubmit(item);
}
public void Delete(T item)
{
var table = this.LookupTableFor(typeof(T));
table.DeleteOnSubmit(item);
}
private ITable LookupTableFor(Type entityType)
{
return dataContext.GetTable(entityType);
}
}
我现在在存储库中有这个类。但我计划把更多的这些放在其他桌子上。这对我来说"感觉"不对。
像这样的多个类别会被认为是最佳实践还是不受欢迎?:
public static class UserQueries
{
public static Employee ByUserName(this IQueryable<Employee> employees, string username)
{
return employees.Where(u => u.User_Name == username).FirstOrDefault();
}
}
此外,我还计划使用另一种方法(GetEmployeeProductivity),该方法本质上使用Employee对象中的数据和单独DataRepository中的数据来应用逻辑。所以现在我使用EmployeeRepository和DataRepository。
这会去哪里?员工类别、服务还是存储库?
通常,根据业务规则做出决策的逻辑位于服务层。从表中创建、更新或删除行的代码(标准CRUD函数)将进入存储库。
因此,如果您需要通过将多个表连接在一起来检索数据,那就在存储库中。表示"如果满足此条件,则对数据库执行此操作"的代码在服务层中。如果您需要在多个表中添加或更新一行,该行仍在存储库中,并且可以在一个方法中完成(如果这两个表在概念上是一个表,但出于数据库效率的原因,如一对多或多对多关系,将其拆分为两个表),也可以使用单独的方法,每个表一个方法,只需从服务层的一个方法调用它们。
您还可以将它们封装在它们引用的每个类中。您的第二个静态类具有返回Employee
对象的方法ByUserName
。您可以将此方法放在Employee类(存储库:EmployeeRepository
)中。但是你有很多选择。在团队中工作时,如果一切都组织得很好,应该会更好。
与repository/UnitOfWork模式相比,设计模式有很多想法,下面是repository&业务层。
***DATA LAYER***
namespace app.data
{
public interface IGenericDataRepository<T> where T : class
{
IList<T> GetAll(params Expression<Func<T, object>>[] navigationProperties);
IList<T> GetList(Func<T, bool> where, params Expression<Func<T, object>>[] navigationProperties);
T GetSingle(Func<T, bool> where, params Expression<Func<T, object>>[] navigationProperties);
void Add(params T[] items);
void Update(params T[] items);
void Remove(params T[] items);
}
}
namespace app.data
{
public class GenericDataRepository<T> : IGenericDataRepository<T> where T : class
{
public virtual IList<T> GetAll(params Expression<Func<T, object>>[] navigationProperties)
{
List<T> list;
using (var context = new GatePassEntities())
{
IQueryable<T> dbQuery = context.Set<T>();
//Apply eager loading
foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
dbQuery = dbQuery.Include<T, object>(navigationProperty);
list = dbQuery
.AsNoTracking()
.ToList<T>();
}
return list;
}
public virtual IList<T> GetList(Func<T, bool> where,
params Expression<Func<T, object>>[] navigationProperties)
{
List<T> list;
using (var context = new GatePassEntities())
{
IQueryable<T> dbQuery = context.Set<T>();
//Apply eager loading
foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
dbQuery = dbQuery.Include<T, object>(navigationProperty);
list = dbQuery
.AsNoTracking()
.Where(where)
.ToList<T>();
}
return list;
}
public virtual T GetSingle(Func<T, bool> where,
params Expression<Func<T, object>>[] navigationProperties)
{
T item = null;
using (var context = new GatePassEntities())
{
IQueryable<T> dbQuery = context.Set<T>();
//Apply eager loading
foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
dbQuery = dbQuery.Include<T, object>(navigationProperty);
item = dbQuery
.AsNoTracking() //Don't track any changes for the selected item
.FirstOrDefault(where); //Apply where clause
}
return item;
}
public virtual void Add(params T[] items)
{
using (var context = new GatePassEntities())
{
foreach (T item in items)
{
context.Entry(item).State = EntityState.Added;
}
context.SaveChanges();
}
}
public virtual void Update(params T[] items)
{
using (var context = new GatePassEntities())
{
foreach (T item in items)
{
context.Entry(item).State = EntityState.Modified;
}
context.SaveChanges();
}
}
public virtual void Remove(params T[] items)
{
using (var context = new GatePassEntities())
{
foreach (T item in items)
{
context.Entry(item).State = EntityState.Deleted;
}
context.SaveChanges();
}
}
}
}
//Domain Models like Employee, Department can be your objectcontext, dbcontext (can be generated by EF or other ORM Tools like T4)
namespace app.data
{
public interface IEmployeeRepository : IGenericDataRepository<Employee>
{
}
public interface IDepartmentRepository : IGenericDataRepository<Department>
{
}
}
***BUSINESS LAYER***
namespace app.business
{
public interface IBusinessLayer
{
IList<Employee> GetAllEmployees();
IList<Employee> GetEmployeesByCountryName(string countryName);
Employee GetEmployeeByName(string EmployeeName);
Employee GetEmployeeByIdentityId(int identityId, string EmployeeUniqueIdentityNumber);
void AddEmployee(params Employee[] Employees);
void UpdateEmployee(params Employee[] Employees);
void RemoveEmployee(params Employee[] Employees);
}
}
public class BuinessLayer : IBusinessLayer
{
private readonly IEmployeeRepository _EmployeeRepository;
public BuinessLayer()
{
_EmployeeRepository = new EmployeeRepository();
}
public BuinessLayer(IEmployeeRepository EmployeeRepository)
{
_EmployeeRepository = EmployeeRepository;
}
public IList<Employee> GetAllEmployees()
{
return _EmployeeRepository.GetAll();
}
public IList<Employee> GetEmployeesByCountryName(string countryName)
{
return _EmployeeRepository.GetList(e => e.Country.Employees.Equals(countryName));
}
public Employee GetEmployeeByName(string EmployeeName)
{
return _EmployeeRepository.GetSingle(
d => d.Name.Equals(EmployeeName),
d => d.Country); //include related employees
}
public Employee GetEmployeeByIdentityId(int identityId, string EmployeeUniqueIdentityNumber)
{
var EmployeeIdentity = _EmployeeIdentityRepository
.GetSingle
(
q => q.IdentityId == identityId && q.UniqueIdentityNumber == EmployeeUniqueIdentityNumber);
Employee Employee = new Employee();
if (EmployeeIdentity != null)
{
Employee = _EmployeeRepository.GetSingle(o => o.EmployeeId == EmployeeIdentity.EmployeeId);
}
else
Employee = null;
return Employee;
}
public void AddEmployee(params Employee[] Employees)
{
try
{
_EmployeeRepository.Add(Employees);
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
}
public void UpdateEmployee(params Employee[] Employees)
{
/* Validation and error handling omitted */
_EmployeeRepository.Update(Employees);
}
public void RemoveEmployee(params Employee[] Employees)
{
/* Validation and error handling omitted */
_EmployeeRepository.Remove(Employees);
}
}
现在您可以从前端调用业务层