EF 关系和规范模式
我一直在研究我的存储库的规范模式,我在存储库中使用 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);
}
I've been looking into the specification pattern for my repositories, I'm using EF4 inside my repositories to query the database and map the selected entities by passing in an expression, something like this:-
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return _objectSet.Where<TEntity>(predicate);
}
This works okay if your just working with the one object set but say if you wanted to select all the comments made by a user that are greater than 128 chars and the user is active. How would you create a specification when two or more object sets are used?
Example:-
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; }
}
To do this in Linq is :-
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;
How would you then convert that to a specification class? Maybe I am just not seeing something as it seems like a reasonable thing to do :)
EDIT
The specification interface:
public interface ISpecification<TEntity>
{
bool IsSatisfiedBy(TEntity entity);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您当前的设置不允许此类查询,因为
User
和Comment
不相关。您只能选择与用户相关帖子相关的所有评论,但您不知道谁发表了评论。只需添加
User
和Comment
之间的关系,您就可以简单地使用:这在您的规范模式中很容易实现。无论如何,如果您想在
Find
方法中从Comment
构建复杂条件,则必须公开导航属性以允许这样做。First of all your current setup doesn't allow such query because
User
andComment
are not related. You can select only all comments related to posts related to user but you don't know who posted comments.Just add relation between
User
andComment
and you can simply use:This will be easily possible in your Specification pattern. Anyway if you want to build complex condition from
Comment
in yourFind
method you must expose navigation properties to allow that.有趣的是,我刚刚阅读了有关 OCP(开闭原则)和规范模式的内容,我想知道是否真的值得在我的项目中实现规范模式。我只是担心我最终可能会得到一大堆规范,因为我有多个实体并且我按多个标准进行查询。
无论如何,这是我最喜欢的一篇(实际上是两篇)关于您正在使用的模式的博客文章(我也在使用):
Entity Framework 4 POCO、存储库和规范模式
重新审视实体框架 4 中的规范模式
Funny I was just reading about OCP (Open Closed Principle) and the Specification pattern, and I was wondering whether it's actually worth implementing the Specification pattern in my project. I'm just worried I might end up with a huge pile of specifications due to the fact that I have several entities and I query by several criteria.
Anyway, here's one (actually two) of my favorite blog posts about the patterns you're using (which I'm using as well):
Entity Framework 4 POCO, Repository and Specification Pattern
Specification Pattern In Entity Framework 4 Revisited