【问题标题】:How to beat 'The memberInfo argument must be for class Game, but was for class BaseEntity. (Parameter 'memberInfo')'?如何击败'memberInfo 参数必须适用于 Game 类,但适用于 BaseEntity 类。 (参数'memberInfo')'?
【发布时间】:2022-01-23 11:32:16
【问题描述】:

我正在使用 sql server 作为数据库从头开始开发一个网络商店(宠物项目)。我使用 EF 核心执行代码优先方法。但是后来我收到了一个任务,我需要使用 MongoDb 作为第二个数据源。 MongoDb 已经有一些数据,我只能对其执行读取操作。所以我想出了一个想法,为我现有的存储库制作一个装饰器,它将连接来自 sql 和 mongo 数据库的数据。我为每个实体编写了BsonClassMap 规则,但这里有个问题:每个实体都派生自 BaseEntity 类

public abstract class BaseEntity
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string Id { get; set; }
    //...
}

例如一些派生实体

public class Game : BaseEntity
{
    public string Key { get; set; }
    //..
}


public class OrderDetail : BaseEntity
{
    public int Quantity { get; set; }
    public string GameId { get; set; }
    public Game Game { get; set; }
    public string OrderId { get; set; }
    public Order Order { get; set; }
}

看看它是如何存储在 mongo 中的 这是产品集合中的一条记录(产品是 sql 数据库中 Game 的模拟) I'm afraid I can't embed pictures in the post due to small reputation but still, you can take a look on it by this link 以及来自供应商收集的一份记录: take a look

您可以看到productsupplier 都有一个_id 字段但它没有意义,因为产品中的SupplierID 字段对应于供应商中的SupplierID(不是_id)字段 因此我打算将 SupplierId 映射到相应供应商 c# 类的 Id 字段,并将 ProductID 映射到 c# Game 类中的 Id 字段。 for better understanding - illustration of how items from product collection supposed to map on Game entity

这是 Game 类型的 BsonClassMap

public class GameMapConfiguration : IBsonClassMapConfiguration
{
    public void Register()
    {
        if (!BsonClassMap.IsClassMapRegistered(typeof(Game)))
        {
            BsonClassMap.RegisterClassMap<Game>(cm =>
            {
                cm.AutoMap();
                cm.SetIgnoreExtraElements(true);
                cm.MapMember(x => x.Id).SetElementName("ProductID").SetSerializer(new StringSerializerFromInt());
                cm.MapMember(x => x.Name).SetElementName("ProductName");
                cm.MapMember(x => x.Description).SetElementName("QuantityPerUnit");
                cm.MapMember(x => x.SupplierId).SetElementName("SupplierID")
                    .SetSerializer(new StringSerializerFromInt());
                //...
            });
        }
    }
}

但是会抛出异常

System.ArgumentOutOfRangeException: 'memberInfo 参数必须是 适用于 Game 类,但适用于 BaseEntity 类。 (范围 'memberInfo')'

我无法在 BsonClassMap 中为 BaseEntity 指定 Id 映射方式,因为 Id has different element names in different collections. Click to see illustration

如何在不改变模型的情况下在这里玩耍?真的可以吗?

【问题讨论】:

    标签: c# mongodb mapping bson


    【解决方案1】:

    您可以为基类注册一个单独的映射。不过,你必须这样做真的很奇怪。我使用 AutoMapper 进行映射,还没有看到这样的怪癖。这种怪癖会破坏继承的意义,并且似乎是实用程序中的一个错误。

    BsonClassMap.RegisterClassMap<BaseEntity>(cm => {
        cm.AutoMap();
        cm.SetIgnoreExtraElements(true);
        cm.MapMember(x => x.Id).SetElementName("ProductID").SetSerializer(new StringSerializerFromInt());
        //...
    });
    

    【讨论】:

    • 正如我所说,我无法在基类中注册它,因为 Product 中 Id 属性的元素名称是“ProductID”,类别 - “CategoryID”,订单 - “OrderID”等。
    • 你试过了吗?
    • 它不适用于产品以外的集合
    • 我决定创建新模型并从其中的 mongo 获取数据,然后使用 automapper 将其映射到域模型
    猜你喜欢
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多