我有两个表,标签(tagid,postid,tagname)和帖子(postid,name,...)
现在我想创建一个查询,返回所有具有一般标签数量的帖子。
喜欢:我想要所有包含标签asp.net和jquery
正如我所说,要查找的标签数量是通用的
我该怎么办?
THX
update 17.11.2009: 有一个问题:表之间的关系不存在,因为我的主键位于2个字段(用于版本控制),如何在没有关系的情况下创建它? 我使用Linq To Entities
此外,查询应该具有良好的性能,并且不应该发出数千个服务器请求。
答案 0 :(得分:6)
你没有说你是在使用L2S,L2O,L2E还是什么。所以这是一个适用于所有这些的扩展方法。我正在猜测对象的布局,所以你可能需要纠正其中一些。
public static IQueryable<Post> WhereHasAllTags(this IQueryable<Post> posts, IEnumerable<string> tags)
{
var q = posts;
foreach (var tag in tags)
{
q = q.Where(p => p.Tags.Any(t => t.Name == tag));
}
return q;
}
现在使用它:
var filtered = Context.Posts.WhereHasAllTags(new [] { "asp.net", "jquery" } );
答案 1 :(得分:4)
最好的办法是调查LinqKit以动态构建谓词。这将允许您将多个谓词连接在一起,因此您只需循环遍历标记以构建最终表达式。
如果您使用的是实体框架而不是Linq2SQL,则需要特别注意,因此发布特定代码有点困难,但该页面上的示例应足以指出您正确的方向。
答案 2 :(得分:1)
IQueryable<Post> FilterByTags(IQueryable<Post> posts, IEnumerable<Tag> tags)
{
foreach (var tag in tags)
{
posts = posts.Where(post => post.Tags.Contains(tag));
}
return posts;
}
您传入的IQueryable<Post>
会添加过滤器,以确保它引用列表中的每个Tag
。
这是一个通用的实现,您可能需要调整,具体取决于您的LINQ提供程序
答案 3 :(得分:1)
我猜你不能使用。我曾遇到过问题的EF 3.5的.Contains()。我通过使用这个“WhereIn”扩展来解决这个问题
'Contains()' workaround using Linq to Entities?
将它放入静态类中,然后你可以使用类似的东西:
IQueryable<Post> PostsWithByTags(IEnumerable<string> tagNames)
{
var postIds = context.Tags.Select(t=>t.postid);
foreach (var tag in tagNames)
{
postIds = context.Tags
.WhereIn(t=> t.postid, postIds)
.Where(t=>t.tagname == tag);
}
return context.Tags.Where( t=> t.posId, postIds)
}
我真的认为你应该考虑在你的桌子之间建立关系。