从Repository <t>?</t>返回数据子集的可能方法

时间:2009-09-21 21:07:54

标签: c# domain-driven-design

假设我需要显示一个客户列表,但只想显示名称,并以某种方式将密钥与列表控件中的名称相关联。

检索整个客户列表及其所有属性可能成本很高。在这种情况下,创建另一个具有所需属性的类(在这种情况下是Id和Name)会更好吗?

基本实现可能如下所示:

public class Customer {
    public int Id { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public int Age { get; set; }
    .....
}

public class CustomerListView {
    public int Id { get; set; }
    public string Name { get; set; }
}

public interface IRepository<T> {
    public T Find(int id);
    public IEnumerable<T> FindAll();
    ....
}

public class Repository<T>: IRepository<T> {
    ....
}

public class CustomerRepository: Repository<Customer> {
    public IEnumerable<CustomerListView> FindAllListView();
}

这种方法是否合适?还有什么其他选择?

4 个答案:

答案 0 :(得分:2)

为了实现这些目标,我创建了一个简单的“View”类,例如CustomerView,它只包含显示概述所需的属性。

My Repository然后有一个方法,它返回这些CustomerView对象的集合。

我主要在我的项目中使用NHibernate。 Nhibernate允许您使用“投影”。 那么,我在我的存储库中做的是: (请注意,下面的代码只是一些伪代码;它不会编译)。

public IList<CustomerView> GetAllCustomers()
{
    ICriteria crit = _session.CreateCriteria (typeof(Customer));

    crit.AddProjection ( ... );

    crit.SetResultTransformer (new EntityToBeanTransformer(typeof(CustomerView));

    return crit.ToList();
}

事实上,它归结为:我告诉我的O / R映射器它应该查询Customers,但它应该返回'CustomerView'类型的实体。 在定义投影的定义中,我还定义Customer类的哪些属性映射到CustomerView类的哪些属性。 然后,O / R映射器足够智能,可以生成一个非常简单的查询,该查询只检索填充CustomerView类所需的那些字段。 例如,执行的查询可以简单如下:

SELECT customerid, customername FROM tblCustomer

答案 1 :(得分:1)

如果你使用IQueryable作为你的回报而不是IEnumerable而不是没有成本:

CustomerRepository()。GetAll()。查找(1)因为在您请求数据之前,AsQueryable实际上并不执行。这意味着LINQ可以将其优化为:

SELECT .... FROM .... WHERE ID = 1而不是

获得一切。找到ID = 1

的地方

请参阅此帖子以获得解释:

Why use AsQueryable() instead of List()?

使用这种方法,您可以创建一个匿名类,并进一步缩小通过线路传输的数据到您想要的范围。这样,LINQ生成的查询就会得到最充分的优化。

答案 2 :(得分:1)

如果您必须从数据库中检索列表,那么您的提案会有所帮助,但我会查看Linq和匿名类型的解决方案。

如果客户列表已经存在于内存中,那么就没有节省。

答案 3 :(得分:0)

你可以使用Linq-to-NHibernate结合Nissan和Frederik(匿名类型和NHibernate)使用的技术。

比尔瓦格纳的更有效的C#项目#31说“使用匿名类型限制类型范围”,我同意。顺便说一下,我推荐整本书。