C# 在一对多实体框架关系中使用动态LINQ

C# 在一对多实体框架关系中使用动态LINQ,c#,entity-framework-6,ienumerable,one-to-many,dynamic-linq,C#,Entity Framework 6,Ienumerable,One To Many,Dynamic Linq,我正在使用EF6和.NET4.5。 我有一个Documents表,其中包含PK DocumentId Int和另一列Title。我有另一个名为DocumentFilters的表,其列为DocumentId Int和DocGUID。两个表之间有一个FK on Doc Id。文档和DocumentFilters表之间是一对多Id的关系。模型如下所示: 我正在尝试使用NuGet包中的DynamicLibrary.cs库编写动态LINQ查询 对于常规Linq,查询在c中类似于: DocDBContext

我正在使用EF6和.NET4.5。 我有一个Documents表,其中包含PK DocumentId Int和另一列Title。我有另一个名为DocumentFilters的表,其列为DocumentId Int和DocGUID。两个表之间有一个FK on Doc Id。文档和DocumentFilters表之间是一对多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);
错误:不存在适用的聚合方法“选择”

错误:DocumentFilters上不存在GUID属性。 这很有意义,因为DocumentFilters是一个集合

我还认为值得一试:

documents = documents.Where("DocumentFilters.AsQueryable().Select(DocGUID).Contains(@0)", gTest);
但是,该库似乎不支持AsQueryable和throws 错误:不存在适用的聚合方法“AsQueryable”


是否可以在Documents表中对可枚举对象的属性编写这样的限制?

尝试使用,它可以用于字符串。

尝试使用,它可以用于字符串。

因此,一种解决方案是通过在ExpressionParser类的IEnumerableSignatures接口中添加Select来修改Dynamic.cs。并将其添加到ParseAggregate方法中:

然而,在此之后,我仍然需要重载Contains方法来处理guid。我没有费心去做那件事。相反,我意识到我可以简单地使用已经支持的.Any代替.Select

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


对不起,浪费了大家的时间

因此,一种解决方案是通过将Select添加到ExpressionParser类中的IEnumerableSignatures接口来修改Dynamic.cs。并将其添加到ParseAggregate方法中:

然而,在此之后,我仍然需要重载Contains方法来处理guid。我没有费心去做那件事。相反,我意识到我可以简单地使用已经支持的.Any代替.Select

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


对不起,浪费了大家的时间

我正在尝试使用它。无论如何,我已经找到了解决办法。谢谢我正在尝试使用它。无论如何,我已经找到了解决办法。谢谢
documents = documents.Where("DocumentFilters.AsQueryable().Select(DocGUID).Contains(@0)", gTest);
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 };
        } 
documents = documents.Where("DocumentFilters.Any(DocGUID.Equals(@0))", gTest); //!!!