Queryable.Intersect() 与 SQLite 和 Linq 未给出预期结果

发布于 2024-10-24 20:47:43 字数 860 浏览 1 评论 0原文

我想通过几个关键字搜索书籍数据库。我提供的关键字越多,搜索范围就越窄。这是我的代码:

var words = text.Split(' ');

IQueryable<Reference> query = null;

foreach (string word in words)
{
    var result = from r in _dbConnection.GetTable<Reference>()
                 where r.Title.Contains(word)
                 || r.ReferenceAuthor.Any(a => a.Person.LastName.Contains(word) || a.Person.FirstName.Contains(word))
                 || r.ReferenceCategory.Any(c => c.Category.Name.Contains(word))
                 || r.ReferenceKeyword.Any(k => k.Keyword.Name.Contains(word))
                 orderby r.Title
                 select r;

    query = query == null ? result : query.Intersect(result);
}

query.OrderBy(r => r.Title);

问题是,我提供的关键字越多,搜索实际上并没有变得更窄。结果甚至根据我提供关键字的顺序而有所不同。 此外,如果涉及多个关键字,则最后一个 OrderBy() 调用将无法可靠地工作。我的想法有缺陷,还是我实现它的方式有缺陷?

I want to search a database of books by several keywords. The more keywords I provide the narrower the search is to be. Here is my code:

var words = text.Split(' ');

IQueryable<Reference> query = null;

foreach (string word in words)
{
    var result = from r in _dbConnection.GetTable<Reference>()
                 where r.Title.Contains(word)
                 || r.ReferenceAuthor.Any(a => a.Person.LastName.Contains(word) || a.Person.FirstName.Contains(word))
                 || r.ReferenceCategory.Any(c => c.Category.Name.Contains(word))
                 || r.ReferenceKeyword.Any(k => k.Keyword.Name.Contains(word))
                 orderby r.Title
                 select r;

    query = query == null ? result : query.Intersect(result);
}

query.OrderBy(r => r.Title);

The problem is, that the search does not in fact get narrower the more keywords I provide. The results even vary depending on the order in which I provide the keywords.
Also, that last OrderBy() call doesn't work reliably if more than one keyword is involved. Is my idea flawed, or the way I implement it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仲春光 2024-10-31 20:47:43

您正在 关闭 word 变量,并遇到 < a href="http://weblogs.asp.net/fbouma/archive/2009/06/25/linq-beware-of-the-access-to-modified-closure-demon.aspx" rel="noreferrer">访问修改闭包问题。

在循环的每次迭代中,您都会将 words 集合中的字符串值捕获到变量 word 中。但是 LINQ 使用延迟执行,并且您的查询直到循环完成后才会执行,此时查询的所有实例都会捕获相同的单词变量 - 因此您会看到结果随着所提供的搜索关键字的顺序而变化。

要解决此问题,请在循环的每次迭代中获取变量的本地副本。

foreach (string w in words)
{
    string word = w;
    ...

You are closing over the word variable, and encountering an access to modified closure problem.

On each iteration of the loop, you are capturing the value of a string from your words collection into the variable word. But LINQ uses deferred execution, and your query does not execute until after the loop is complete, at which point the same word variable is captured by all instances of your query - hence you are seeing your results vary with the order of the search keywords provided.

To fix this, take a local copy of the variable on each iteration of the loop.

foreach (string w in words)
{
    string word = w;
    ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文