【发布时间】: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
您可以看到product 和supplier 都有一个_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
如何在不改变模型的情况下在这里玩耍?真的可以吗?
【问题讨论】: