Hello everyone. I work with mongoDb Driver 2.18.0
I have objects two different classes that implement the same interface. I store these objects in a mongo DB which works fine. The problem is the deserialization of this objects when I filter on interface properties.
My data modeling
// my interface
public interface IAudit
{
DateTime TimeStamp { get; set; }
string IpAddress { get; set; }
}
// first implementation
public class AuditEdi : IAudit
{
public DateTime TimeStamp { get; set; }
public string IpAddress { get; set; }
public string MessageType { get; set; }
....
}
// second implementation
public class AuditIhm : IAudit
{
public Guid UserId { get; set; }
public DateTime TimeStamp { get; set; }
public string IpAddress { get; set; }
...
}
Class Map registration
BsonClassMap.RegisterClassMap<AuditIhm>(cm =>
{
cm.SetDiscriminator("AuditIhm");
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
});
BsonClassMap.RegisterClassMap<AuditEdi>(cm =>
{
cm.SetDiscriminator("AuditEdi");
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
});
Try to filter on one of the interface’s property
var filter = Builders<IAudit>.Filter.Eq(r => r.IpAddress, ipAddress);
var sort = Builders<IAudit>.Sort.Descending("TimeStamp");
var findOptions = new FindOptions<IAudit>() {Sort = sort};
the exception
System.InvalidOperationException : ‘Unable to determine the serialization information for r => r.IpAddress.’
Should i use class inheritance instead of interface for modeling my documents or is it possible to use this implementation ?
1 Like
Hi, @Yannick_Darcillon,
Welcome to the MongoDB Community Forums. I understand that you’ve encountered an unexpected serialization-related exception. When I ran your code (with some minor alterations to fill in the missing gaps), I did not encounter an exception.
using System;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
BsonClassMap.RegisterClassMap<AuditIhm>(cm =>
{
cm.SetDiscriminator("AuditIhm");
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
});
BsonClassMap.RegisterClassMap<AuditEdi>(cm =>
{
cm.SetDiscriminator("AuditEdi");
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
});
var client = new MongoClient();
var db = client.GetDatabase("test");
var coll = db.GetCollection<ILifeCycleAudit>("coll");
var ipAddress = "127.0.0.1";
var filter = Builders<ILifeCycleAudit>.Filter.Eq(r => r.IpAddress, ipAddress);
var sort = Builders<ILifeCycleAudit>.Sort.Descending("TimeStamp");
var query = coll.Find(filter).Sort(sort);
Console.WriteLine(query);
// my interface
public interface ILifeCycleAudit
{
DateTime TimeStamp { get; set; }
string IpAddress { get; set; }
}
// first implementation
public class AuditEdi : ILifeCycleAudit
{
public DateTime TimeStamp { get; set; }
public string IpAddress { get; set; }
public string MessageType { get; set; }
}
// second implementation
public class AuditIhm : ILifeCycleAudit
{
public Guid UserId { get; set; }
public DateTime TimeStamp { get; set; }
public string IpAddress { get; set; }
}
The output of this code is:
find({ "IpAddress" : "127.0.0.1" }).sort({ "TimeStamp" : -1 })
Please provide a self-contained repro of the issue so that we can investigate further.
Sincerely,
James
I forgot the most important line of code in my example, the execution of the query ! If you add this the problem will appear :
coll.Find(filter).Sort(sort).ToEnumerable();
IEnumerable will not execute the query until you enumerate over the data.
best regard,
Yannick