代码之家  ›  专栏  ›  技术社区  ›  Joepro

从存储库返回数据子集的可能方法?

  •  3
  • Joepro  · 技术社区  · 15 年前

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

    检索整个客户列表及其所有财产可能会很昂贵。在这个场景中,用所需的属性(在本例中是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 回复  |  直到 15 年前
        1
  •  1
  •   Community CDub    8 年前

    如果您使用iQuery作为您的退货而不是IEnumerable,则无需支付任何费用:

    customerRepository().getAll().find(1),因为在请求数据之前,AsQueryable实际上不会执行。这意味着Linq可以将其优化为:

    选择…从…其中id=1而不是

    得到一切。找到id=1的位置

    有关解释,请参阅本文:

    Why use AsQueryable() instead of List()?

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

        2
  •  2
  •   Frederik Gheysels    15 年前

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

    然后,我的存储库有一个方法,该方法返回这些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映射器它应该查询客户,但是它应该返回“customerview”类型的实体。 在投影的定义中,我还定义了客户类的哪些属性映射到客户视图类的哪些属性。 然后,O/R映射器足够智能,可以生成一个非常简单的查询,该查询只检索填充customerview类所需的字段。 例如,执行的查询可以简单到:

    SELECT customerid, customername FROM tblCustomer
    
        3
  •  1
  •   Henk Holterman    15 年前

    如果您必须从数据库中检索列表,那么您的建议是有意义的,但是我将研究一个LINQ和匿名类型的解决方案。

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

        4
  •  0
  •   Martin R-L    15 年前

    你可以结合尼桑和弗雷德里克(匿名类型和NHibernate)使用的技术,使用LINQ到NHibernate。

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