【问题标题】:Why am I getting Error retrieving mongo document in .net?为什么我在 .net 中检索 mongo 文档时出错?
【发布时间】:2020-03-25 15:43:30
【问题描述】:

我已将文档插入到 MongoDB 的集合中

public class Product :BaseDocument, IProduct
    {
        public Guid ProductId { get; set; }
        public string ProductName { get; set; }
        public Guid AccountId { get; set; }
        public List<IProductDetail> ProductDetailList { get; set; } = new List<IProductDetail>();
    }

public class ProductDetail:IProductDetail
        {
            public Guid ProductDetailId { get; set; }
            public string ProductDetailCode { get; set; }
        }

当我尝试检索这个时,我得到一个错误

public List<IProduct> GetProductsList(Guid accountId)
        {
            IEnumerable<IProduct> prodList = new List<Product>();
            IMongoCollection<Product> products = _database.GetCollection<Product>("Products");
            prodList = products.Find(m => m.AccountId == accountId).ToList();
            return prodList.ToList();
        }

报错如下

System.FormatException: '反序列化时出错 Entities.ProductDetail 类的 ProductDetailList 属性:未知 鉴别器值'ProductDetail'。'

我做错了什么?

【问题讨论】:

    标签: c# .net mongodb mongodb-.net-driver


    【解决方案1】:

    您收到此错误的原因是 MongoDB .NET 驱动程序不知道如何解析 IProductDetail 并尝试实例化 ProductDetail 类,因为有一个代表该类型的 _t 字段存储在MongoDB。

    通常您可以在那种polymorphic scenario 中使用BsonKnownTypes,但它仅适用于类和结构。所以如果你想在这里保留一些类层次结构,那么你需要引入一个抽象类并在那里应用这个属性。

    [BsonKnownTypes(typeof(ProductDetail))]
    public abstract class ProductDetailBase: IProductDetail
    {
    }
    
    public class ProductDetail : ProductDetailBase
    {
        public Guid ProductDetailId { get; set; }
        public string ProductDetailCode { get; set; }
    }
    

    然后你可以使用:

    public List<ProductDetailBase> ProductDetailList { get; set; } = new List<ProductDetailBase>();
    

    在这种情况下,您可以有一个类层次结构,MongoDB .NET 驱动程序将在运行时将您的 BSON 文档反序列化为适当的子类。

    【讨论】:

    • 谢谢。这行得通。它确实让一切都变得非常混乱......有没有更好的方法来做到这一点?即使用 BSON 对象?
    • @coolblue2000 这真的取决于你想要达到的目标。当我看到接口时,我假设您需要某种多态性,并且您希望将类层次结构存储在单个字段下。如果是这样,请阅读我链接的文章 - 它深入描述了这个领域。 .NET 中的接口是“虚拟的”,而您在 Mongo 中尝试序列化/反序列化的类型必须知道如何解析为具体类,因此您不能将接口用作属性类型,但是当您需要层次结构时(多态) 那么你可以利用BsonKnownTypes
    猜你喜欢
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 2017-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多