【发布时间】:2018-07-06 08:00:09
【问题描述】:
我正在尝试使用 LINQ 表达式来查询 MongoDB 中的简单集合,但目前当根文档包含由 C# 模型中的接口表示的嵌入式文档时,我遇到了问题。在当前的 MonboDB C# 2.5.0 驱动程序中,我正在发生这种情况。
我整理了一个重现我的问题的示例。如果我有一对这样定义的类:
public class MainClass
{
[BsonId]
public Guid Id { get; set; }
public String Name { get; set; }
public InnerClass Child { get; set; }
}
public class InnerClass
{
public String Name { get; set; }
}
我可以通过以下 Linq 查询毫无问题地查询它:
var entity = collection.AsQueryable<MainClass>().SingleOrDefault(x => x.Child.Name.Equals("Some Value"));
但是,如果我将模型更改为以下内容(基本上用接口替换直接类引用):
public class MainClass : IMainClass
{
[BsonId]
public Guid Id { get; set; }
public String Name { get; set; }
public IInnerClass Child { get; set; }
}
public class InnerClass : IInnerClass
{
public String Name { get; set; }
}
public interface IMainClass
{
Guid Id { get; set; }
String Name { get; set; }
IInnerClass Child { get; set; }
}
public interface IInnerClass
{
String Name { get; set; }
}
当执行相同的查询时,我得到以下异常:
System.InvalidOperationException: '{document}.Child.Name is not supported.'
当使用标准 mongodb 查询(使用通用签名中的接口或具体类)进行查询时,这两个示例都可以正常工作:
var entity = collection.Find(Builders<IMainClass>.Filter.Eq("Child.Name", "Some Value")).SingleOrDefault();
围绕 MongoDB C# Driver 源代码进行调试,问题似乎发生在 PredicateTranslator 类周围的某处尝试时:
TryGetFieldExpression(expression, out fieldExpression)
由于某种原因,在失败的示例中,Expression 节点以“System.Linq.Expressions.PropertyExpression”类型到达,它无法转换为“MongoDB.Driver.Linq.Expressions.IFieldExpression”。同时,在工作示例中,Expression 节点带有“MongoDB.Driver.Linq.Expressions.FieldExpression”类型,当然,它可以很好地转换为“MongoDB.Driver.Linq.Expressions.IFieldExpression”。
我还能够验证,在这两个示例中,表达式树到达驱动程序时是相同的,但它们的结构在 PipelineBinder 阶段开始不同。
最后,我的问题是:这应该有效吗?首先建模的文档是错误的吗?关于如何让它发挥作用的任何建议?
【问题讨论】:
标签: c# .net mongodb linq driver