1

我有一个包含以下内容的域模型:

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?还有其他方法可以做到这一点吗?

4

1 回答 1

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 转换器(您可以将实际的评论属性保留为延迟加载,因为您可能不会使用它)

于 2011-10-16T21:42:22.197 回答