在何处放置存储库的多个查询

本文关键字:查询 存储 在何处 | 更新日期: 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);
        }
}

现在您可以从前端调用业务层