我不确定在哪里对业务对象进行特定的查询。
当我们开始对存储库模式使用多个特定于表的查询时,在哪里 这些应该放在哪?服务层或存储库?
例如请参见下文:
例如:
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。
这会去哪儿?员工类,服务或存储库?
答案 0 :(得分:1)
通常,根据业务规则做出决策的逻辑在服务层中。从表(标准CRUD函数)创建,更新或删除行的代码将进入存储库。
因此,如果您需要通过将多个表连接在一起来检索数据,那么就在存储库中。显示“如果满足此条件,然后对数据库执行此操作”的代码位于服务层中。如果你需要在几个表中添加或更新一行,它仍然在存储库中,并且可以在一个方法中完成(如果2个表在概念上是一个,但由于数据库效率原因分成两个,如一个许多或多对多关系),或者您可以使用单独的方法,每个表一个,只需从服务层中的一个方法调用它们。
答案 1 :(得分:0)
您还可以做的是将它们封装在它们引用的每个类中。您的第二个静态类具有返回ByUserName
对象的方法Employee
。您可以将此方法放在Employee类(The Repository:EmployeeRepository
)中。但你有很多选择。如果一切都井然有序,那么在团队中工作时应该会更好。
答案 2 :(得分:0)
由于设计模式与存储库/ UnitOfWork模式相比有很多想法,这里是存储库和标准实现的标准实现。业务层。
***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);
}
}
现在您可以从前端
调用业务层