Interface Mongodb-属性具有接口返回类型时如何反序列化

Interface Mongodb-属性具有接口返回类型时如何反序列化,interface,mongodb-.net-driver,Interface,Mongodb .net Driver,我试图避免在我的数据层和使用该层的客户机代码之间引入任何依赖关系,但在尝试使用Mongo(使用MongoRepository)时遇到了一些问题 MongoRepository显示了创建反映数据结构的类型以及在需要时继承实体的示例。例如 [CollectionName("track")] public class Track : Entity { public string name { get; set; } public string hash { get; set; }

我试图避免在我的数据层和使用该层的客户机代码之间引入任何依赖关系,但在尝试使用Mongo(使用MongoRepository)时遇到了一些问题

MongoRepository显示了创建反映数据结构的类型以及在需要时继承实体的示例。例如

[CollectionName("track")]
public class Track : Entity  
{
    public string name { get; set; }
    public string hash { get; set; }

    public Artist artist { get; set; }
    public List<Publish> published {get; set;}
    public List<Occurence> occurence  {get; set;}
}
[CollectionName(“曲目”)]
公共类轨道:实体
{
公共字符串名称{get;set;}
公共字符串哈希{get;set;}
公共艺术家{get;set;}
已发布的公共列表{get;set;}
公共列表出现{get;set;}
}
为了在我的客户机代码中使用这些,我想用接口替换Mongo特定的类型,例如:

[CollectionName("track")]
public class Track : Entity, ITrackEntity 
{
    public string name { get; set; }
    public string hash { get; set; }

    public IArtistEntity artist { get; set; }
    public List<IPublishEntity> published {get; set;}
    public List<IOccurenceEntity> occurence  {get; set;}
}
[CollectionName(“曲目”)]
公共类跟踪:实体,ITrackEntity
{
公共字符串名称{get;set;}
公共字符串哈希{get;set;}
公共艺术能力艺术家{get;set;}
已发布的公共列表{get;set;}
公共列表出现{get;set;}
}
但是,Mongo驱动程序不知道如何处理这些接口,我可以理解地得到以下错误:

反序列化类sf.data.mongodb.entities.Track的Artister属性时出错:找不到sf.data.IArtistEntity类型的序列化程序。-->MongoDB.Bson.BsonSerializationException:未找到sf.data.IArtistEntity类型的序列化程序。


有人对我应该如何处理这个问题有什么建议吗?

好的-所以我找到了我自己问题的答案-我想如果有人有类似的问题,我会与大家分享

我正在寻找的功能是BsonClassMap.RegisterClassMap

这允许您显式定义域类的哪些属性/字段应该被序列化/反序列化(注意,它取代了任何自动映射-您需要定义希望包含的所有字段/属性)。它解决了对具有接口类型的属性进行反序列化的问题,没有进一步的问题

BsonClassMap.RegisterClassMap<Track>(cm =>
{
    cm.MapProperty<IArtistEntity>(c => (IArtistEntity)c.Artist);
    cm.MapProperty<List<IOccurenceEntity>>(c => (List<IOccurenceEntity>)c.Occurence);
    cm.MapProperty(c => c.hash);
    cm.MapProperty(c => c.name);
    cm.MapProperty(c => c.published);

});
BsonClassMap.RegisterClassMap(cm=>
{
cm.MapProperty(c=>(i强度)c.Artist);
cm.MapProperty(c=>(列表)c.occurrence);
映射属性(c=>c.hash);
cm.MapProperty(c=>c.name);
cm.MapProperty(c=>c.published);
});

我所做的很简单,我想这会帮到你。我的问题和之前回答的一些评论者一样,所以我自己做了更多的测试。这对我有用

如果有用于接口的具体类型,则可以手动注册为接口类型的具体类型生成的序列化程序

你的情况也是如此

    BsonSerializer.RegisterSerializer(
        typeof(IPublishEntity), 
        BsonSerializer.LookupSerializer<Publish>());
BsonSerializer.RegisterSerializer(
类型(IPublishEntity),
BsonSerializer.LookupSerializer());

BsonSerializer.RegisterSerializer(
类型(IOCCURENCENTITY),
BsonSerializer.LookupSerializer());
我认为还需要指出的是,在注册序列化程序之前,我还在为我的具体类型手动注册类映射。我没有这样做就测试了这个方法。若你们还并没有这样做,我不确定LookupSerializer方法是否会失败,但那个看起来是这样的

    BsonClassMap.RegisterClassMap<Publish>(cm => {
        cm.AutoMap();
    });
BsonClassMap.RegisterClassMap(cm=>{
cm.AutoMap();
});

BsonClassMap.RegisterClassMap(cm=>{
cm.AutoMap();
});

值得一提的是,我在其他任何地方都没有见过这种解决方案。不完全确定原因,但当一些看似显而易见的东西没有出现在谷歌的雷达上时,我通常会有点怀疑。希望这对其他人有所帮助。

请注意,您可以先调用
cm.AutoMap()
,这将首先映射整个类。然后可以使用
cm.MapProperty
覆盖需要指定的属性。很好的建议-我希望在为我所有的类显式定义映射之前我已经发现了这一点!我对你在这里做的事很困惑。我假设您使用的是第二个版本的类跟踪,即带有属性接口的版本。于是,Track.artist返回了一个持久性。在你的类地图中,你正在将它投射到它已经是的东西上,iAtistity?cm.MapProperty(c=>(i强度)c.Artist);演员组到底为你做了什么?这对反序列化有什么帮助?mongo反序列化程序不需要知道具体的IARTIStenty类型吗?
    BsonClassMap.RegisterClassMap<Publish>(cm => {
        cm.AutoMap();
    });
    BsonClassMap.RegisterClassMap<Occurence>(cm => {
        cm.AutoMap();
    });