EF关系和规范模式

时间:2011-03-28 09:27:30

标签: c# entity-framework-4 repository specifications

我一直在研究我的存储库的规范模式,我在我的存储库中使用EF4来查询数据库并通过传入一个表达式映射所选实体,如下所示: -

public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
    return _objectSet.Where<TEntity>(predicate);
}

如果您只使用一个对象集,但是如果您想要选择用户所做的大于128个字符并且用户处于活动状态的所有注释,则此工作正常。当使用两个或多个对象集时,您将如何创建规范?

示例: -

class User
{
    public string Name { get; set; }
    public bool Active { get; set; }
    public virtual ICollection<Post> Posts { get; set; }

    public User()
    {
        Posts = new List<Post>();
    }
}

class Post
{
    public string Text { get; set; }
    public DateTime Created { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }

    public Post()
    {
        Comments = new List<Comment>();
    }
}

class Comment
{
    public string Text { get; set; }
    public DateTime Created { get; set; }
}

要在Linq中执行此操作: -

var results = from u in users
              from p in u.Posts
              from c in p.Comments
              where u.Active && c.Text.Length > 128
              select c;

您如何将其转换为规范类?也许我只是没有看到一些东西,因为这似乎是一件合理的事情:)

修改

规范界面:

public interface ISpecification<TEntity>
{
    bool IsSatisfiedBy(TEntity entity);
}

2 个答案:

答案 0 :(得分:1)

首先,您当前的设置不允许此类查询,因为UserComment无关。您只能选择与用户相关的帖子相关的所有评论,但您不知道谁发布了评论。

只需添加UserComment之间的关系,您就可以使用:

var results = from c in context.Comments
              where c.User.Active and c.Text.Length > 128
              select c;

这在您的规格模式中很容易实现。无论如何,如果你想在Comment方法中从Find构建复杂条件,你必须公开导航属性以允许它。

答案 1 :(得分:0)

有趣的是我刚刚阅读了有关OCP(开放封闭原则)和规范模式的内容,我想知道是否真的值得在我的项目中实现规范模式。我只是担心我可能最终得到一大堆规格,因为我有几个实体并且我按几个标准查询。

无论如何,这里有一篇(实际上是两篇)我最喜欢的博客文章,关于你正在使用的模式(我也在使用):

Entity Framework 4 POCO, Repository and Specification Pattern

Specification Pattern In Entity Framework 4 Revisited