存储库模式和返回类型
本文关键字:返回类型 模式 存储 | 更新日期: 2023-09-27 18:25:40
我使用的是存储库模式,其中每个数据库表有一个存储库类。我想知道你们是如何处理只需要返回特定列数的查询的
例如,假设我有以下
项目表(虚构表)
ItemId
Name
PurchaseDate
Description
Price
在我的代码中,我用上面的字段创建了一个名为Item.cs的对象(目前没有使用orm)。
如果我有多个场景需要返回
- 项目ID
- 购买日期和名称的组合
- ItemId和价格
哪种方法是最好的?
- 从items表中获取所有字段并返回一个Item对象(1个repo查询)
- 在Repo中创建三个查询,并为每个查询返回一个Item对象
- 在回购中创建三个查询,只返回需要的内容
现在想象一下这个场景,其中有一个超过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中,或者只使用域类,知道它没有完全"水合"。