在一对多 Entity Framework 关系中使用 Dynamic LINQ Where

Using Dynamic LINQ Where in a one-to-many Entity Framework relationship

我正在使用 EF 6 和 .net 4.5。 我有一个 "Documents" table 和 PK "DocumentId" (Int) 和另一列 "Title"。我有另一个名为 "DocumentFilters" 的 table,其列为 "DocumentId"(Int)和 "DocGUID"(Guid)。两个 table 之间的 "Doc Id" 上有一个 FK。它是 Documents 和 DocumentFilters tables 之间的一对多 Id 关系。模型看起来像这样:

我正在尝试使用 NuGet 包中的 DynamicLibrary.cs 库编写动态 LINQ 查询。

使用常规 Linq,查询在 c# 中看起来像这样:

DocDBContext db = new DocDBContext();
var documents = db.Documents.Include(d => d.DocumentFilters);
Guid gTest = Guid.Parse("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");

documents = documents.Where(d => d.DocumentFilters.Select(f => f.DocGUID).Contains(gTest));

这非常有效,可以检索由我感兴趣的 GUID 过滤器分隔的文档。但是,我需要将它动态地放置在过滤器字符串中,其中可能包含其他过滤器。有可能这样做吗?我试过这样的代码:

documents = documents.Where("DocumentFilters.Select(DocGUID).Contains(@0)", gTest);

错误:不存在适用的聚合方法'Select'

documents = documents.Where("DocumentFilters.DocGUID=@0", gTest);

错误:GUID 属性 在 DocumentFilters 上不存在。 (这是有道理的,因为 DocumentFilters 是一个集合)。

我也认为可能值得试一试:

documents = documents.Where("DocumentFilters.AsQueryable().Select(DocGUID).Contains(@0)", gTest);

但同样,它看起来不像库支持 AsQueryable 并抛出 错误:不存在适用的聚合方法 'AsQueryable'。

是否可以在文档 table 中对可枚举对象的 属性 写入这样的限制?

尝试使用Dynamic Linq,可以对字符串使用

所以一种解决方案是修改Dynamic.cs,在ExpressionParserIEnumerableSignatures接口中添加“Select” class。并将其添加到 ParseAggregate() 方法中:

if (signature.Name == "Min" || signature.Name == "Max")
        {
            typeArgs = new Type[] { elementType, args[0].Type };
        }
        else if (signature.Name == "Select")
        {
            typeArgs = new Type[] { elementType, Expression.Lambda(args[0], innerIt).Body.Type };
        } 

但是,在此之后我仍然需要重载 Contains() 方法来使用 GUID。我懒得那样做。相反,我意识到我可以简单地使用已经支持的 .Any() 而不是 .Select()!

documents = documents.Where("DocumentFilters.Any(DocGUID.Equals(@0))", gTest); //!!!

我还必须将列名称从“GUID”更改为“DocGUID”,因为在写入 GUID.Equals() 时限制字符串,解析器将其误认为是 GUID 类型而不是列名,并抛出 Equals() 不是 GUID 类型的有效扩展名的错误。

抱歉浪费了大家的时间!