C# 数据过滤是否在控制器、服务或存储库层中进行?

C# 数据过滤是否在控制器、服务或存储库层中进行?,c#,asp.net-mvc,asp.net-mvc-3,entity-framework-4.1,repository,C#,Asp.net Mvc,Asp.net Mvc 3,Entity Framework 4.1,Repository,我使用的是ASP.netmvc3。我按以下顺序获取视图的数据: Controller -> Service Layer -> Repository 在我的存储库中,我有一个GetAll方法,它返回特定对象(如Category)的所有记录 所以,若我需要一个所有类别的列表,那个么在我的控制器中,我会有如下内容: IEnumerable<Category> categories = categoryService.GetAll(); public IEnumerable&

我使用的是
ASP.netmvc3
。我按以下顺序获取视图的数据:

Controller -> Service Layer -> Repository
在我的存储库中,我有一个GetAll方法,它返回特定对象(如Category)的所有记录

所以,若我需要一个所有类别的列表,那个么在我的控制器中,我会有如下内容:

IEnumerable<Category> categories = categoryService.GetAll();
public IEnumerable<Category> GetAll()
{
     return categoryRepository.GetAll();
}
在我的服务层中,我可以:

public IEnumerable<Category> GetParentCategories()
{
     return categoryRepository.GetAll.Where(x => x.ParentCategoryId == null);
}
public IEnumerable GetParentCategories()
{
返回categoryRepository.GetAll.Where(x=>x.ParentCategoryId==null);
}
或者我的服务层必须是这样的:

public IEnumerable<Category> GetParentCategories()
{
     return categoryRepository.GetParentCategories();
}
public IEnumerable<Category> GetParentCategories()
{
     return GetAll()
          .Where(x => x.ParentCategoryId == null);
}
public IEnumerable GetParentCategories()
{
return categoryRepository.GetParentCategories();
}
然后在我的存储库层中,如下所示:

public IEnumerable<Category> GetParentCategories()
{
     return categoryRepository.GetParentCategories();
}
public IEnumerable<Category> GetParentCategories()
{
     return GetAll()
          .Where(x => x.ParentCategoryId == null);
}
public IEnumerable GetParentCategories()
{
返回GetAll()
。其中(x=>x.ParentCategoryId==null);
}

请有人帮我澄清一下我的困惑。可能会有不同的情况。我可能会带回所有具有活动状态的类别。我可能会带回处于非活动状态的类别。那么我是否需要为每个层提供一个方法?

您应该尽可能从数据源中筛选出最接近的记录,否则您将检索到上层的记录,这些记录将由于筛选选项而被丢弃。这不能很好地扩展,所以您需要在所有需要它的层上公开过滤功能,但要确保实际的过滤是在尽可能低的层上执行的,通常是在数据库级别执行的

在您发布的示例中,如果使用
GetAll
,它将返回所有记录的
IEnumerable
,然后才应用筛选,您将来会遇到问题,因为您基本上是将整个表加载到内存中,然后才应用筛选

因为您使用的是EF,所以可以利用
IQueryable
的延迟执行属性。检查:


更新:跟进您的评论,您还应检查:


您应该始终尝试从数据库中获取尽可能少的数据。因此,您应该在存储库类中执行所有过滤

许多文章建议您创建和使用通用存储库。但我认为,当应用程序增长时,它们将无法很好地工作。我建议您使用适当的搜索方法创建适当的存储库类,如:

emailRepository.GetForUser("Ada");
userRepository.GetNewUsers();
首先,隐藏实现细节,比如如何识别新用户。与使用一般查询相比,它还使代码更易于理解和扩展

您还可以添加一些筛选选项:

emailRepository.GetForUser("Ada", Filtering.New().Paged(1, 20).SortedBy("FirstName"));

与@JoãoAngelo不同,我不建议您在存储库之外使用
IQueryable
。通过这样做,您将把数据库执行移到存储库类之外。这意味着存储库无法处理任何错误。

GetAll Wha只是一个示例方法,主要关注过滤部分。然后我是否在存储库中为每次使用创建一个方法?但是.Where(…)不是像带Where子句的sql select一样工作吗?只有当您使用LINQ to实体时,并且需要一个
IQueryable
。是的。我有一个方法Get tat在存储库中是可查询的,因此存储库可以处理向它抛出的所有条件。GetALlUsers()方法会让我解雇员工。这是非常低效的。拉入100.9000个用户,以获得一个名称-编号。