【问题标题】:LINQ Query to find all tags?LINQ Query 查找所有标签?
【发布时间】:2010-08-25 22:01:30
【问题描述】:

我有一个名为 Notes 的管理文档的应用程序。与博客一样,Notes 可以搜索与一个或多个标签的匹配项,这些标签包含在 Note.Tags 集合属性中。标记具有名称和 ID 属性,并根据 ID 进行匹配。用户可以指定多个标签进行匹配,在这种情况下,注释必须包含指定匹配的所有标签。

我有一个非常复杂的 LINQ 查询来执行便笺搜索,其中包含扩展方法和循环。坦率地说,它有一种真正的代码味道。我想用更简单的东西重写查询。我知道如果我将 Tag 设为一个简单的字符串,我可以使用如下内容:

var matchingNotes = from n in myNotes
                    where n.Tags.All(tag => searchTags.Contains(tag))

如果我的模型使用带有 ID 的 Tag 对象,我可以做这么简单的事情吗?查询会是什么样子。它可以用流利的语法编写吗?那会是什么样子?

【问题讨论】:

标签: linq


【解决方案1】:

我相信您可以在单个 LINQ 表达式中找到具有相关标签的注释:

IQueryable<Note> query = ... // top part of query

query = query.Where(note => searchTags.All(st =>
    note.Tags.Any(notetag => notetag.Id == st.Id)));

不幸的是,AllAny 没有等效的“流利语法”,所以你能做到的最好的就是

query = from note in query
        where searchTags.All(st =>
            note.Tags.Any(notetag => notetag.Id == st.Id))
        select note;

这也好不了多少。

【讨论】:

  • 查询抛出此错误:'无法创建'Tag'类型的常量值。此上下文仅支持原始类型('例如 Int32、String 和 Guid')。'
  • 它对我来说很好,所以你的代码一定有一些你没有告诉我们的东西。例如,您确定 Tag.Idstring 类型吗?
  • 其实TagID就是Type GUID。
  • @David Veeneman:我相信我已经回答了您的问题。如果您认为我没有,请编辑问题以澄清仍然缺少哪些信息。如果您还有其他问题,可以发布一个新的单独问题。
  • 我相信我发现了问题——它与 LINQ to Entities 相关,而不是您的查询。 LTE 中的 All() 方法似乎存在问题。见stackoverflow.com/questions/879411/…
【解决方案2】:

对于初学者,请参阅我的评论;我怀疑查询是错误的!我会通过简单地分别强制每个标签存在来简化它:

IQueryable<Note> query = ... // top part of query
foreach(var tagId in searchTagIds) {
    var tmpId = tagId; // modified closures...
    query = query.Where(note => note.Tags.Any(t => t.Id == tmpId));
}

这应该具有强制所有指定的标签都存在并说明的净效果。

【讨论】:

  • 你好,你能回答this
【解决方案3】:

Timwi 的解决方案适用于大多数 LINQ 方言,但不适用于 Linq to Entities。我确实找到了一个有效的单语句 LINQ 查询,由 ReSharper 提供。基本上,我编写了一个 foreach 块来进行搜索,ReSharper 提出将该块转换为 LINQ 语句——我不知道它可以做到这一点。

我让 ReSharper 执行转换,这是它给我的:

return searchTags.Aggregate<Tag, IQueryable<Note>>(DataStore.ObjectContext.Notes, (current, tag) => current.Where(n => n.Tags.Any(t => t.Id == tag.Id)).OrderBy(n => n.Title));

我使用 Entity Framework 4 从数据库中读取了我的 Notes 集合。DataStore 是我用来管理我的 EF4 连接的自定义类;它将 EF4 ObjectContext 作为属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    相关资源
    最近更新 更多