use*_*107 1 c# sql-server asp.net-mvc entity-framework
我有一个名为Article的表:
-Id
-Title
-Content
-Tags (This is a comma seperated list of tags e.g. 'Sports,Italy,Ferrari')
Run Code Online (Sandbox Code Playgroud)
使用实体框架我希望能够找到所有具有特定标签的文章.
List<Article> GetArticles(List<String> tags)
{
//do an entity framework query here to find all articles which have the tags specified
}
Run Code Online (Sandbox Code Playgroud)
返回的条目应包含指定的所有标记.例如,如果函数的输入是'car','blue',则应返回具有这些至少这2个标记的所有条目.
我无法想象我将如何实现这一点.我知道如何使用存储过程实现这一点,这是我的计划b.
存储过程实际上是一个很好的选择,如果不是最好的选择,真的.但是,您仍然可以通过Contains以下方式实现:
var articles = db.Articles.Where(m => tags.Any(t => m.Tags.Contains(t)));
Run Code Online (Sandbox Code Playgroud)
这样做基本上是遍历传入的标签,并创建一个查询是否Tags与任何一个相似的查询.请记住,因为这将是一个LIKE查询,它将是sloooooowwwww,除非您的Tags列被索引,这也需要是一个定义的长度,而不是像NVARCHAR(MAX).
另一个潜在的问题是假匹配.假设您有标签"Read"和"Reading",因为这是一个LIKE查询,搜索"Read"标签将返回两者.实际上,解决这个问题的唯一方法是在数据中添加标记分隔符,例如:"[Read],[Reading]".然后,您搜索而不是"[Read]",而不是"Read",并且您保证只撤回正确的.
当我需要打包/解压这样的字符串时,我通常会做类似的事情:
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; }
Run Code Online (Sandbox Code Playgroud)
这看起来相当复杂,但所有这一切都在于setter正在解析分隔符上的标记列表,删除我选择使用的短语分隔字符,[以及].getter将列表打包回一个包含所有内容的字符串.
这允许您随后使用TagsList,字符串版本将自动保留,而不必考虑它.但是,在查询时,您仍然需要查询Tags,因为这是实际的数据库支持的属性.
| 归档时间: |
|
| 查看次数: |
2449 次 |
| 最近记录: |