存储库模式和返回类型

时间:2012-02-23 18:52:54

标签: c# asp.net-mvc repository repository-pattern

我使用的是存储库模式,每个数据库表都有一个存储库类。我想知道你们如何处理只需要返回特定数量的列的查询

例如说我有以下

项目表(虚构表格)

ItemId
Name
PurchaseDate
Description
Price

在我的代码中,我使用上面的字段创建一个名为Item.cs的对象(当前不使用orm)。

如果我有多个场景我需要返回

  1. 项目Id
  2. PurchaseDate和Name
  3. 的组合
  4. ItemId和价格
  5. 哪种方法最好?

    1. 从items表中获取所有字段并返回Item对象(1个repo查询)
    2. 在Repo中创建三个查询并为每个查询返回一个Item对象
    3. 在Repo中创建三个查询并仅返回所需内容?
    4. 现在假设这个场景中有一个包含超过10个字段的表。

      就个人而言,我喜欢选项一,但我不确定是否有更好的方法来解决这个问题。

5 个答案:

答案 0 :(得分:7)

我个人使用通用类型存储库,并阅读AsQueryable()

这是界面。

interface IRepository<T>
{
    void Create(T item);
    IQueryable<T> Retrieve();
    void Update(T item);
    void Delete(T item);
    void SubmitChanges();
}

这是实施。

public class PersonsRepository : IRepository<Person>
{
    private DataContext dc;

    public PersonsRepository(DataContext dataContext)
    {
        dc = dataContext;
    }

    public void Create(Person Person)
    {
        dc.Persons.Add(Person);
    }

    public IQueryable<Person> Retrieve()
    {
        IQueryable<Person> Person = (from s in dc.Persons
                                       select s);
        return Person.AsQueryable();

    }

    public void Update(Person Person)
    {
        Person _Person = (from s in dc.Persons
                            where s.ID == Person.ID
                            select s).Single();
        {
            _Person.LastLogin = Person.LastLogin;
            _Person.Password = Person.Password;
            _Person.LastUpdate = Person.LastUpdate;
            // Cannot change your username.
        }
    }

    public void Delete(Person Person)
    {
        dc.Persons.Remove(Person);
    }

    public void SubmitChanges()
    {
        dc.SaveChanges();
    }
}

现在,如果您需要查询存储库,则需要执行此类操作 原谅我,下面的代码未经测试,我实际上更像是一个VB人:(
希望你明白这一点

public class PersonsService
{
    private PersonRepository<Person> personRepository;

    public PersonService()
    {
        personRepository = new PersonRepository<Person>();
    }

    public UsablePerson GetPersonByID(int ID)
    {
        UsablePerson person = (from p in personRepository<Person>.Retrieve
                               where p.ID = ID
                               select new UsablePerson { p.FirstName, 
                                                         p.LastName, 
                                                         p.EmailAddress }).FirstOrDefault();

        return person;
    }
}

出于我的目的,我在这个特定的项目上使用LINQ,但是这可以适应你喜欢的任何数据层...这就是存储库层的美妙。

从这里开始,我“个人”还有一个服务层来处理数据连接的细微差别......例如GetPersonByIDGetPeopleSince(DateTime marker)。这是我删除不需要的信息(IE:密码)并将剩余信息存储在ViewModel或其他POCO中的地方。

答案 1 :(得分:7)

我在需要时将方法添加到我的存储库,与通用存储库相比,无论您是否需要它们,都可以获得一组方法。

返回IQueryable是一个漏洞抽象。

看一下Domain Driven Design(这本书),你会很清楚设计好的存储库应该是什么样子。

我还写了一篇关于通用存储库的咆哮:http://blog.gauffin.org/2012/02/generic-repositories-a-silly-abstraction-layer/

答案 2 :(得分:2)

如果您考虑域驱动设计,单个对象具有不同配置的事实很可能表示不同的域。这并不需要每个都有不同的对象,但这是一个很好的模式。实现此目的的一种方法是使用基本类和极简主义属性集。然后,您可以创建更多从“基础”继承的“特定于域”的类。

至于返回数据,有多种方法可以“流量覆盖”流量。例如,多个存储库可以很好地分离出域。但这增加了复杂性(除非绝对需要,否则不是一个好主意)。我不喜欢返回不同对象的单个存储库。如果你有一些可以为空的属性(可能),那就更容易接受了。

我不喜欢LINQ to SQL作为DAL,正如@KethiS所建议的那样,但我在企业环境中工作,而LINQ to SQL基本上是大规模的。否则使用LINQ很棒。只是我的两分钱。

如果您可以返回一种对象类型,那就更好了。如果对象的差异基于权限,请考虑清除用户不应看到的数据。但是请注意,如果要抓取大量对象,这不是可扩展的。

答案 3 :(得分:0)

我喜欢基于Linq的存储库来处理这类事情。 Linq2SQL,MSEF或Linq2NH允许您通过Select()方法定义列列表。然后,您将收到仅使用您指定的内容填充的域对象或实体类。您可以使用其他代码将其映射到DTO,或者只使用域类,因为它知道它没有完全“保湿”。

答案 4 :(得分:0)

为什么在实际只需要少数字段时会返回所有字段?如果您担心性能,请选择您真正想要的字段。我不是严格遵循设计模式的忠实粉丝,也许你应该考虑根据你的要求改变设计。