【问题标题】:C# - MongoDB Linq Query failing with embedded document interfaceC# - 带有嵌入式文档界面的 MongoDB Linq 查询失败
【发布时间】: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


    【解决方案1】:

    您可以强制转换嵌套接口。所以表达式看起来像:

    var entity = collection.AsQueryable<MainClass>().SingleOrDefault(
        x => (InnerClass)x.Child.Name.Equals("Some Value")
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-06
      • 2011-02-15
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-20
      相关资源
      最近更新 更多