我有Fluent映射,将虚构的类Customer映射到Orders列表。现在我想从数据库中获取所有客户而不加载订单。这可以在查询/标准/ etc中以某种方式指定,还是LazyLoading唯一的解决方案?
虚构课程:
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Order> Orders { get; set; }
}
public class Order
{
public virtual int Id { get; set; }
// ++
}
答案 0 :(得分:2)
无论如何,延迟加载会自动执行此操作,您是否尝试避免延迟加载?为什么呢?
例如:
IList<Customer> customers = _session.CreateCriteria<Customer>().List<Customer>();
仅为您提供所有客户。只有在客户实体上调用Order集合时,才会从数据库中获取订单,例如:
foreach(Customer customer in customers)
{
IList<Order> orders = customer.Orders; // Will hit the database
}
因此,如果您有10个客户,此代码将在数据库中点击11次(1个用于获取客户,10个用于检索每个客户的订单)。这会给你一个SELECT N + 1问题,但如果你对每个客户的订单不感兴趣,那么就不要调用Orders,它们也不会被提取。我不是故意粗鲁,但这似乎相当明显,我是否误解了你的问题?
更新:回应评论。如果通过Web服务发送POCO,您应该考虑使用报表查询,因为您的POCO将丢失其对NHibernate会话对象的附件,因此延迟加载将不起作用(Orders集合将只返回NULL)。换句话说,正确调用您的Web服务的“事物”不会对NHibernate或您的域模型有任何了解,所以:
public IList<CustomerView> GetAllCustomers()
{
return (from c in _session.Query<Customer>()
select new CustomerView()
{
Id = c.Id,
Name = c.Name
}).ToList();
}
public CustomerDetail GetCustomerFromId(int id)
{
return (from c in _session.Query<Customer>()
where c.Id == id
select new CustomerDetail()
{
Id = c.Id,
Name = c.Name
FullAddress = c.FormatFullAddress(),
Orders = c.Orders,
// other properties (snip)
}).SingleOrDefault();
}
这是使用NHibernate 3.0内置的LINQ提供程序,如果您不使用NHibernate 3.0,并且可以使用Projections进行报表查询。语法逃脱了我,请尝试http://nhibernate.info/doc/nh/en/index.html#querycriteria-projection
答案 1 :(得分:1)
您可以在条件中指定FetchMode:
var crit = session.CreateCriteria (typeof(SomeObject));
crit.SetFetchMode ("association", FetchMode.Eager);
您还可以在映射中指定不应延迟加载关联/集合。默认情况下,集合是延迟加载的。