如何根据子集合中的值选择对象?

Posted

技术标签:

【中文标题】如何根据子集合中的值选择对象?【英文标题】:How to select objects based on values in sub collection? 【发布时间】:2021-04-12 00:55:48 【问题描述】:

我有一份文件清单。一个文档是这样的:

class Document

    string Name;
    string Description;
    List<Page> Pages;

一个页面是这样的:

class Page

    string OCR;

在 fluent LINQ 中针对 ef core 5 的以下查询是什么?: 我想获取名称、描述或 OCR 中包含“文本”的所有文档。

是否可以使用单个流畅的 LINQ 查询获取文档? 我想出了这个,但我不知道如何添加 OCR 位:

Documents.Where (   
                    x =>    x.Name.ToUpper ().Contains (text) 
                    ||      x.Description.ToUpper ().Contains (text)
                ).ToList ();

我知道我可以在 Document 上添加一个属性,例如 OCR,检索所有文档,然后在内存中返回页面中的所有 OCR 文本,然后在查询中执行类似的操作

Documents.Where (   
                    x =>    x.Name.ToUpper ().Contains (text) 
                    ||      x.Description.ToUpper ().Contains (text)
                    ||      x.OCR.ToUpper ().Contains (text)
                ).ToList ();

并且可能还有其他解决方案,但我想知道是否可以单独在 LINQ 中针对数据库执行此操作。

提前致谢!

【问题讨论】:

我没有做太多的 EF 所以我不知道这是否正确地转换为 SQL,但是你需要像 x.Pages.Any(p =&gt; p.OCR.ToUpper().Contains(text)) 这样的东西吗?我也不知道.ToUpper() 是否是最好的方法,这取决于它的翻译方式。 【参考方案1】:

您可以简单地将页面作为条件包含在内,它应该在 EF 的查询翻译中正确翻译。

这是一个示例,带有示例数据:

var Documents = new List<Document>()
    
        new Document
        
            Name = "nottext",
            Description = "nottext",
            Pages = new List<Page>
            
                new Page
                
                    OCR = "text"
                
            
        ,
        new Document
        
            Name = "nottext",
            Description = "nottext",
            Pages = new List<Page>
            
                new Page
                
                    OCR = "text"
                
            
        
    ;

Documents.Where(d =>
       d.Name.Contains("text", StringComparison.OrdinalIgnoreCase)
    || d.Description.Contains("text", StringComparison.OrdinalIgnoreCase)
    || d.Pages.Any(p => p.OCR.Contains("text", StringComparison.OrdinalIgnoreCase)));

【讨论】:

谢谢,它就像一个魅力。唯一的问题是我不能使用StringComparison.OrdinalIgnoreCase,因为它会抛出一个错误,指出无法翻译表达式。但这不是问题,因为我可以使用ToUpper。我使用 SQLite 作为数据库引擎。

以上是关于如何根据子集合中的值选择对象?的主要内容,如果未能解决你的问题,请参考以下文章

使用 CollectionGroupQuery 的子集合中的 Firestore 写入限制

在子集合中的项目内容上创建计算属性

有没有办法获取子集合中的所有文档(Firestore)

如何从所有文档的子集合中检索所有数据

FireStore 文档如何在子集合中读取计算

如何读取地图中的 Firestore 值?