使用NHibernate过滤延迟加载集合的内容

时间:2011-10-16 21:21:01

标签: 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 bool Private { get; set; }
}

我有一个服务层,通过它我可以检索这些实体,并且传递给该服务层的参数是请求用户的身份。

我想要做的是能够在服务层中构建一个DetachedCriteria来限制为给定客户返回的Comment项,这样就不会向用户显示任何评论不属于他们并被标记为私人。

我尝试过这样的事情:

criteria.CreateCriteria("Comments")
    .Add(Restrictions.Or(Restrictions.Eq("Private", false),
                         Restrictions.And(Restrictions.Eq("Private", true),
                                          Restrictions.Eq("CreatedBy.Id", requestingUser.Id))));

但是这并没有流向延迟加载的评论。

我不想使用过滤器,因为这需要与会话进行交互(当前没有暴露给服务层)或强迫我的存储库知道用户上下文(这似乎是太多的逻辑什么应该是一个愚蠢的层)。由于其他原因,过滤器也是一种肮脏的解决方案 - 确定可见内容和不可见内容的逻辑比私有标记更详细。

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

使用DetachedCriteria是否可以实现这一点?还有其他方法可以做到这一点吗?

1 个答案:

答案 0 :(得分:1)

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

这可以更好地处理,无论是直接调用存储库服务,还是通过实体本身,通过创建一个专门执行此操作的方法。

为了最好地适应您当前的模型,我会接受您当前所做的调用,以使实体返回视图模型而不仅仅是实体;

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

然后在你的服务方法中(我在这里做了一些猜测)

public PostForUser GetPost(int postId, User requestingUser){

   ...
}

然后,您可以以最有效的方式创建和填充PostForUser视图模型,可能是通过分离的条件,或者通过单个查询和DistinctRootEntity Transformer(您可以将实际的comments属性保留为延迟加载,因为您可能赢了)不使用它)

相关问题