在哪里为存储库放置多个查询

时间:2014-04-18 15:05:53

标签: c# design-patterns repository-pattern

我不确定在哪里对业务对象进行特定的查询。

当我们开始对存储库模式使用多个特定于表的查询时,在哪里 这些应该放在哪?服务层或存储库?

例如请参见下文:

例如:

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。

这会去哪儿?员工类,服务或存储库?

3 个答案:

答案 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);
        }
}

现在您可以从前端

调用业务层