使用存储库模式进行查询

时间:2014-09-05 14:33:32

标签: c# linq design-patterns linq-to-sql repository-pattern

我有以下数据库模型: enter image description here 我使用Linq-to-SQL和Design Pattern Repository描述了不合时宜的页面http://www.remondo.net/repository-pattern-example-csharp/

这是一个类图:

enter image description here

我希望像这样进行查询,而是使用Repository Design Pattern

ExampleRepositoryDataSet data = new ExampleRepositoryDataSet();
var query = from hotel in data.Hotel
            join category in data.Category on hotel.Category equals category.IdCategory
            join country in data.Country on hotel.Contry equals country.IdContry
            where country.Name == "Cuba"
            orderby hotel.Rating descending
            group new {hotel, category, country} by category.Name;

2 个答案:

答案 0 :(得分:1)

你可以这样做:

public class HotelRepository : EFRepository<Hotel>, IHotelRepository
{
     public List<IGrouping<string, Hotel>> GetAllByCountrynameOrderedByCountrynameAndGroupedByCategoryname(string categoryName, string countryName)
     {
          return DbSet
              .Where(hotel => hotel.Country.Name.Equals(countryName))
              .OrderByDescending(hotel => hotel.Rating)
              .GroupBy(hotel => hotel.Category.Name)
              .ToList();
     }
}

答案 1 :(得分:0)

  1. Repository隐藏了您的ORM(Linq-2-SQL,这也是过时的,使用EF更好),即Repository包含对ORM呈现的数据集ExampleRepositoryDataSet的引用我可以看到。
  2. Repository通常根据Add, Delete, Edit, ListAll方法进行描述,因此其实现可以(并且必须)使用Linq-2-SQL功能进行查询构建。这就是你在做什么。
  3. 您可以使用方法Repository填充ListHotelsByCountryNameAndOrder(string countryName, bool isAsc),并按照您刚刚撰写的方式实施。{/ li>
  4. 如果你想使用generic repository(有人告诉它反模式,但我不同意),你的问题会变得更加困难,但仍然可以解决。看看Specification模式。
  5. 最后,Query Object Pattern有点过时了。今天.NET表达似乎是一个很好的选择。对于简单过滤,您可以使用方法IEnumerable<T> ListAll(Expression<Func<T, bool>> filter)填充存储库,并像myRepo.ListAll(t => t.Name == "Cuba")一样使用它。对于复杂查询,它是添加新方法(3.)或使用规范(4。)的更好方法。
  6. 不要从存储库返回IQueryable。始终调用.ToList()或其他非延迟操作来加载数据。