我有一个名为Article的表:
-Id
-Title
-Content
-Tags (This is a comma seperated list of tags e.g. 'Sports,Italy,Ferrari')
使用实体框架我希望能够找到所有具有特定标签的文章。
List<Article> GetArticles(List<String> tags)
{
//do an entity framework query here to find all articles which have the tags specified
}
返回的条目应包含指定的所有标记。 例如如果函数的输入是'car','blue',那么应该返回所有带有这两个标签的条目。
我无法想象如何实现这一点。我知道如何使用存储过程实现这一点,这是我的计划b。
答案 0 :(得分:5)
存储过程实际上是一个不错的选择,如果不是最好的选择,真的。但是,您仍然可以使用Contains
:
var articles = db.Articles.Where(m => tags.Any(t => m.Tags.Contains(t)));
这样做基本上是迭代传入的标签并创建一个查询,以测试Tags
是否与任何这些相似。请记住,因为这将是一个LIKE查询,它将成为sloooooowwwww,除非您的Tags
列被索引,这也需要定义长度,而不是像NVARCHAR (MAX)。
另一个潜在问题是错误匹配。让我们说你有标签,&#34;阅读&#34;和&#34;阅读&#34;,因为这是一个LIKE查询,搜索&#34; Read&#34;标签,将返回两者。实际上,解决这个问题的唯一方法是在数据中添加标记分隔符,例如:&#34; [读取],[阅读]&#34;。然后,您搜索而不是&#34; [Read]&#34;,而不是&#34; Read&#34;,并且您保证只撤回正确的。
当我需要打包/解压缩这样的字符串时,我通常会做类似的事情:
public string Tags
{
get
{
return TagsList != null
? String.Join(",", TagsList.Select(tag => "[" + tag + "]"))
: null;
}
set
{
TagsList = !String.IsNullOrWhiteSpace(value)
? value.Replace("[", "").Replace("]", "").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList()
: new List<string>();
}
}
[NotMapped]
public List<string> TagsList { get; set; }
这看起来相当复杂,但所有这一切都是因为setter正在解析分隔符上的标记列表,删除了我选择使用的短语分隔字符,[
和{{ 1}}。 getter将列表打包回一个字符串中。
这使您可以使用]
,并且字符串版本将自动保留,而不必考虑它。但是,在查询时,您仍然需要查询TagsList
,因为这是实际的数据库支持的属性。
答案 1 :(得分:0)
由于没有允许在查询中进行解析的构造,因此可以使用以下技巧
var query = db.Articles
.Where(article => tags.All(tag => ("," + article.Tags + ",").Contains("," + tag + ",")))
.ToList();
它基本上与解析相反,它通过使用EF支持的string.Contains和Enumerable.All构造检查表字段是否包含所有传递的标记。要正确处理字符串中的第一个/最后一个标记,需要在开头/结尾连接逗号。
答案 2 :(得分:0)
如何在列中使用逗号分隔数据。
例如:Ienumerable<string> searchItems
---它会列出说A,B,C
有列的表订阅---有数据说“E,A,R,C,B,D,H”
因此我们需要谓词生成查询,其中where子句具有搜索生成查询的结果:
WHERE Subscribe LIKE'%A%' OR LIKE'%B%' OR LIKE'%C%'
目前已生成:
WHERE Subscribe LIKE'%A%' AND LIKE'%B%' AND LIKE'%C%'
当我们尝试 - searchItems.ForEach(y => query = query.Where(y => y.Subscribe.Contains(y)));
答案 3 :(得分:-1)
您需要一个csv parser.实体框架,只能将字段(标签)作为字符串变量。然后,解析器就能将该单个字符串拆分为List Tags。