在Repository模式中,我应该在哪里实现Distinct方法

本文关键字:在哪里 实现 Distinct 方法 我应该 Repository 模式 | 更新日期: 2023-09-27 17:59:20

我有标准的Repository接口设置:

public interface IRepository<T, TKey> : IDisposable where T : class
{
    T Get(TKey id);
    IEnumerable<T> Get();
    IEnumerable<T> Find(Expression<Func<T, bool>> whereClause);
    T Add(T entity);
    void Delete(T entity);
    bool Save();
    int Update(T entity);
}

它有一个实现:

public class EfRepository<T, TKey> : IRepository<T, TKey> where T : class
{
    protected DbContext _context;
    public EfRepository(DbContext context) { ...}
    public virtual T Get(TKey id) {...}
    public virtual IEnumerable<T> Get() { ...}
    public virtual IEnumerable<T> Find(Expression<Func<T, bool>> whereClause)  { ...}
    public T Add(T entity) { ...}
    public void Delete(T entity) { ...}
    public bool Save() { ...}
    public int Update(T entity) { ...}
}

在所有这些之上,我有一个服务层:

public class VehicleService: IVehicleService
{
    private readonly IRepository<Vehicle, int> _repository;
    public VehicleService(IRepository<Vehicle, int> repository)
    {
        _repository = repository;
    }
    public IEnumerable<int> GetModelYears()
    {
        // ?? help?
    }
}

我的问题是,在哪里实现Distinct方法?LINQ查询如下所示:

context.Set<Vehicle>().Select(x => x.ModelYear).Distinct();

我还没有弄清楚如何在存储库级别对Distinct方法进行通用编码,我认为这不是放置它的正确位置

我们已选择不在我们的存储库中返回IQueryable。但我也没有向服务层公开任何实际的DbSet对象。

也许更好的问题是,这是一种正确的做事方式吗?有更好的方法吗?

在Repository模式中,我应该在哪里实现Distinct方法

如果这只是一种对象,而不是存储库中的所有对象,那么您可以创建一个新的存储库,包含该查询,但基于IRepository构建。

public interface IVehicleRepository : IRepository<Vehicle>{
    IEnumerable<int> GetDistinctVehicle();
}
public VehicleRepository : EfRepository<Vehicle>, IVehicleRepository{
    public VehicleRepository(DbContext context) : base(context)
    {
    }

    public IEnumerable<int> GetDistinctVehicle(){
        Context.Set<Vehicle>().Select(x=> x.ModelYear).Distinct();
    }
}

这样,您仍然可以使用所有的IRepositorystuff,但也可以使用您的额外方法。只需在您选择的注入器中将IVehicleDepository绑定到VehicleDeposity,并将其注入构造函数,就像使用IReposities一样。

这里有几个选项:

1) 最有效的方法是执行

context.Set<Vehicle>().Select(x => x.ModelYear).Distinct();

部分。正如您可能已经知道的,这将确保sql查询在返回结果集之前在数据库级别执行distinct。这样可以确保不会从数据库中返回大型数据集,只会使.Net进一步限制内存中的结果集。从那里,您可以让_vehicleService.GetModelYears调用_vehicreDepository.GetDistinctModelYears.

2) 如果您使用的是一个非常小的数据集,并且在满行的手上执行内存中的Distinct函数所带来的性能影响无关紧要,那么您可以:a) 让服务中的"GetModelYears()"方法调用_vehicleDepository.GetVehicles()方法,然后b)对从存储库返回的车辆列表执行Distinct。