问题
First up, I know there is already questions out there with this error message, but I haven't found any that relate to the use of using interfaces with this type of query.
I'm currently trying to update a MongoDB entity using the C# Driver 2.0. However, I'm getting an error when it's trying to build the query (I'm assuming it's the Builders<T>.Filter.Eq(i => i.Id, entity.Id)
bit of code) and I'm getting the following error:
Unable to determine the serialization information for i => i.Id.
I've got the following class that I'm trying to update
public interface IEntity {
string Id { get; set; }
}
public interface ITrack : IEntity {
string Name { get; set; }
}
public class TrackDTO : ITrack
{
[BsonId]
public string Id { get; set; }
public string Name { get; set; }
}
I'm then using the interface to save the object into the database using the following method in a generic DAO class to replace the entire document. Note, in the example below T is coded as ITrack
(i.e. TrackDao = new Dao<ITrack>
) but when the object is passed in at runtime it's a TrackDTO
object (which is correct):
public async Task<T> Save(T entity)
{
// Save the entity to the collection.
ReplaceOneResult result = await _collection.ReplaceOneAsync(Builders<T>.Filter.Eq(i => i.Id, entity.Id), entity, new UpdateOptions() { IsUpsert = true });
// return the saved user object.
return entity;
}
I don't know if the Id property of my IEntity
class also requires the [BsonId]
attribute, but I'd like to avoid this if possible, as I want to keep my model layer (where IEntity
resides) free of any database platform specific references.
I've also tried adding the following class map which has had no effect either:
BsonClassMap.RegisterClassMap<TrackDTO>(cm =>
{
cm.AutoMap();
cm.MapMember(c => c.Id).SetSerializer(new StringSerializer(BsonType.ObjectId));
cm.SetIdMember(cm.GetMemberMap(c => c.Id));
});
For the same reason as not having the [BsonId]
attributes in the Model layer, I don't want to have the Model classes decorated with [BsonKnownTypes]
that reference DTO objects, however I don't mind if this needs to occur as part of a class map.
回答1:
- For
"Unable to determine the serialization information for i => i.Id."
Try to use: nameof()
.
Builders<T>.Filter.Eq(nameof(IEntity.Id), entity.Id)
2.
...but I'd like to avoid this if possible, as I want to keep my model layer (where IEntity resides) free of any database platform specific references.
My solution for problem like your and similar problems:
public interface IEntity {
[BsonId]
string Id { get; set; }
string IdEntity { get; set; }
}
[BsonIgnoreExtraElements(Inherited = true)]
public abstract class BaseEntity : IEntity
{
[BsonRepresentation(BsonType.ObjectId)]
public virtual string Id { get; set; }
[BsonIgnoreIfNull]
public string IdEntity { get; set; }
}
来源:https://stackoverflow.com/questions/31531990/unable-to-determine-the-serialization-information-for-i-i-id-using-interfaces