存储库模式和返回类型

本文关键字:返回类型 模式 存储 | 更新日期: 2023-09-27 18:25:40

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

例如,假设我有以下

项目表(虚构表)

ItemId
Name
PurchaseDate
Description
Price

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

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

  1. 项目ID
  2. 购买日期和名称的组合
  3. ItemId和价格

哪种方法是最好的?

  1. 从items表中获取所有字段并返回一个Item对象(1个repo查询)
  2. 在Repo中创建三个查询,并为每个查询返回一个Item对象
  3. 在回购中创建三个查询,只返回需要的内容

现在想象一下这个场景,其中有一个超过10个字段的表。

就我个人而言,我喜欢第一种选择,但我不确定是否有更好的方法。

存储库模式和返回类型

当我需要方法时,我会将它们添加到我的存储库中,而普通存储库中无论你是否需要,都可以获得一组方法。

返回IQueryable是一个泄漏抽象。

看看《领域驱动设计》(这本书),你会很好地了解设计良好的存储库应该是什么样子。

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

我个人使用通用类型存储库,并读取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,但它可以适应您喜欢的任何数据层。。。这就是存储库层的美妙之处。

从这里开始,我"个人"还有一个服务层,它处理数据连接的细微差别。。。例如CCD_ 3或CCD_。这就是我去掉不需要的信息(IE:密码)并将剩余信息存储在ViewModel或其他POCO中的地方。

如果你想到域驱动设计,单个对象具有不同配置的事实很可能表明不同的域。这并不需要每个对象都有不同的对象,但这是一个很好的模式。实现这一点的一种方法是拥有一个具有最小属性集的基类。然后创建更多"特定于域"的类,这些类继承自基本类。

至于返回数据,有多种"流量拦截"流量的方式。例如,多个存储库很好地分离了域。但这增加了复杂性(除非绝对需要,否则这不是一个好主意)。我不喜欢单个存储库返回不同的对象。如果你有一些可以为null的属性(也许),这是可以接受的。

正如@KethiS所建议的那样,我不喜欢将LINQ to SQL作为DAL,但我在企业环境中工作,LINQ to SQL在规模上基本上很糟糕。以其他方式使用LINQ是很棒的。只有我的两美分。

如果您可以返回一个对象类型,那就更好了。如果对象之间的差异是基于权限的,请考虑清除用户不应该看到的数据。但是,请注意,如果您正在抓取大量对象,则这是不可伸缩的。

当您实际上只需要几个字段时,为什么要返回所有字段?如果您担心性能问题,请选择您真正需要的字段。我不太喜欢严格遵循设计模式,也许你应该考虑根据你的要求修改设计。

我喜欢这类基于Linq的存储库。Linq2SQL、MSEF或Linq2NH将允许您通过Select()方法定义列列表。然后,您将收到一个域对象或实体类,该类只填充了您指定的内容。您可以使用额外的代码将其映射到DTO中,或者只使用域类,知道它没有完全"水合"。