使用NHibernate筛选延迟加载集合的内容

使用NHibernate筛选延迟加载集合的内容,nhibernate,detachedcriteria,Nhibernate,Detachedcriteria,我有一个域模型,其中包括以下内容: public class Customer : EntityBase<Customer>, IAggregateRoot { public IList<Comment> Comments { get; set; } } public class Comment : EntityBase<Comment> { public User CreatedBy { get; set; } public boo

我有一个域模型,其中包括以下内容:

public class Customer : EntityBase<Customer>, IAggregateRoot
{
    public IList<Comment> Comments { get; set; }
}

public class Comment : EntityBase<Comment>
{
    public User CreatedBy { get; set; }
    public bool Private { get; set; }
}
criteria.CreateCriteria("Comments")
    .Add(Restrictions.Or(Restrictions.Eq("Private", false),
                         Restrictions.And(Restrictions.Eq("Private", true),
                                          Restrictions.Eq("CreatedBy.Id", requestingUser.Id))));
但这不会传递到延迟加载的注释

我不喜欢使用过滤器,因为这需要与当前未向服务层公开的会话进行交互,或者迫使我的存储库了解用户上下文,这在本应是哑层的情况下似乎太多逻辑。由于其他原因,过滤器也是一个肮脏的解决方案——决定什么是可见的,什么不是的逻辑比私有标志更详细

我不想在服务层中使用LINQ来过滤集合,因为这样做会以一种非常糟糕的方式破坏整个延迟加载的好处。评论不相关的客户列表将导致数据库调用风暴,这将非常缓慢。我不希望在我的表示层中使用LINQ作为MVC应用程序,因为它似乎是一个错误的地方


您知道使用DetachedCriteria是否可行吗?实现这一点的任何其他方法?

让实体本身根据某些外部值为集合属性公开一组不同的值对我来说似乎不正确

这将得到更好的处理,无论是直接调用存储库服务,还是通过实体本身,通过创建一个方法来具体实现这一点

不过,为了最适合您当前的模型,我会让您当前进行的调用获取实体返回viewmodel,而不仅仅是实体

public class PostForUser
{
    public Post Post {get; set;}
    public User User {get; set;}
    public IList<Comment> Comments}
}

然后,您将以最有效的方式创建和填充PostForUser视图模型,可能是通过分离的条件,或者通过单个查询和DistincTrotenty转换器,您可以将实际的comments属性留给lazy load,因为您可能不会使用它,所以让实体本身根据某些外部值为集合属性公开一组不同的值对我来说似乎是不正确的

这将得到更好的处理,无论是直接调用存储库服务,还是通过实体本身,通过创建一个方法来具体实现这一点

不过,为了最适合您当前的模型,我会让您当前进行的调用获取实体返回viewmodel,而不仅仅是实体

public class PostForUser
{
    public Post Post {get; set;}
    public User User {get; set;}
    public IList<Comment> Comments}
}

然后,您将以最有效的方式创建和填充PostForUser视图模型,可能是通过分离的条件,或者通过单个查询和DistincTrotenty Transformer,您可以将实际的comments属性留给lazy load,因为您可能不会使用它

我实际上在MVC应用程序中构建了ViewModels,但是你的答案让我考虑了一些我以前没有做过的事情——在实体本身上添加了一个用户用户方法的注释,它将返回一个LINQ过滤的评论集合。作为一个域实体,这个过滤概念是域的一个重要部分,我不认为这是一个重叠的关注点。是的,这是我实际做的方式。但是,我不会使用LINQ过滤comments属性,我会调用存储库来只获取用户的注释,这样您就不必从DB加载所有注释来只选择一个fewBut,要做到这一点,您需要使用DI设置一个存储库接口,因此,您的域可以与数据层分开,但这是另一回事……是的,如果可能的话,我宁愿将存储库排除在域对象之外,即使使用NHibernate,没有简单的POCO。我会记住这一点,如果性能失控的道路。我实际上在MVC应用程序中构建ViewModels,但是你的答案让我考虑了我以前没有的东西——在实体本身上添加了一个用户用户方法的注释,它将返回一个LINQ过滤的评论集合。作为一个域实体,这个过滤概念是域的一个重要部分,我不认为这是一个重叠的关注点。是的,这是我实际做的方式。但是,我不会使用LINQ过滤comments属性,我会调用存储库来只获取用户的注释,这样您就不必从DB加载所有注释来只选择一个fewBut,要做到这一点,您需要使用DI设置一个存储库接口,因此,您的域可以与数据层分开,但这是另一回事……是的,如果可能的话,我宁愿将存储库排除在域对象之外,即使使用NHibernate,没有简单的POCO。我会记住这一点,如果今后的表现无法控制。