admin管理员组文章数量:1344540
Issue
We have a custom serializer for an enum (MeasurementValueType), which stores the enum as a string in MongoDB and deserializes it from a string back into the enum when querying. The enum MeasurementValueType is declared as ushort. If it is not then everything works as expected. We are using Mongo C# driver version 2.30 and trying to upgrade to linq provider v# from V2.
Setup
A simple class with an enum property:
public class TestA
{
public MeasurementValueType ValueType { get; set; }
}
Custom serializer for MeasurementValueType:
public class MeasurementValueTypeSerializer : StructSerializerBase<MeasurementValueType>
{
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, MeasurementValueType value)
{
BsonSerializer.Serialize(context.Writer, value.ToString());
}
public override MeasurementValueType Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var measurementValueType = (MeasurementValueType)Enum.Parse(
args.NominalType,
BsonSerializer.Deserialize<string>(context.Reader)
);
return measurementValueType;
}
}
Registered in startup:
BsonSerializer.RegisterSerializer(typeof(MeasurementValueType), new MeasurementValueTypeSerializer());
Expected Behavior
When saving a document, ValueType should be stored as a string in MongoDB. When querying, the deserializer should convert it back to the enum.When inserting an object the serializer is called and the enum is persisted as a string. When fetching it back as a whole document, the deserializer is called.
Problem
If I query using LINQ, the deserializer is not applied and no match is found:
database.TestACollection.Insert(new TestA { ValueType = MeasurementValueType.Angle });
var match = database.TestACollection
.AsQueryable()
.Single(x => x.ValueType == MeasurementValueType.Angle);
This worked fine in LINQ Provider v2, but in LINQ Provider v3, it no longer matches.
Question
Why isn't the right-hand expression (MeasurementValueType.Angle) passed to the serializer so it can be converted to a string before executing the query? I understand that we do not whant to deserialize the stored properties but my right-hand expression i.e. the enum could be serialized to the same format (string) for fast comparison on the database side.
Is there a workaround to ensure the serializer is respected in LINQ queries?
Can I register the serializer in a different way so that LINQ v3 applies it?
Issue
We have a custom serializer for an enum (MeasurementValueType), which stores the enum as a string in MongoDB and deserializes it from a string back into the enum when querying. The enum MeasurementValueType is declared as ushort. If it is not then everything works as expected. We are using Mongo C# driver version 2.30 and trying to upgrade to linq provider v# from V2.
Setup
A simple class with an enum property:
public class TestA
{
public MeasurementValueType ValueType { get; set; }
}
Custom serializer for MeasurementValueType:
public class MeasurementValueTypeSerializer : StructSerializerBase<MeasurementValueType>
{
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, MeasurementValueType value)
{
BsonSerializer.Serialize(context.Writer, value.ToString());
}
public override MeasurementValueType Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var measurementValueType = (MeasurementValueType)Enum.Parse(
args.NominalType,
BsonSerializer.Deserialize<string>(context.Reader)
);
return measurementValueType;
}
}
Registered in startup:
BsonSerializer.RegisterSerializer(typeof(MeasurementValueType), new MeasurementValueTypeSerializer());
Expected Behavior
When saving a document, ValueType should be stored as a string in MongoDB. When querying, the deserializer should convert it back to the enum.When inserting an object the serializer is called and the enum is persisted as a string. When fetching it back as a whole document, the deserializer is called.
Problem
If I query using LINQ, the deserializer is not applied and no match is found:
database.TestACollection.Insert(new TestA { ValueType = MeasurementValueType.Angle });
var match = database.TestACollection
.AsQueryable()
.Single(x => x.ValueType == MeasurementValueType.Angle);
This worked fine in LINQ Provider v2, but in LINQ Provider v3, it no longer matches.
Question
Why isn't the right-hand expression (MeasurementValueType.Angle) passed to the serializer so it can be converted to a string before executing the query? I understand that we do not whant to deserialize the stored properties but my right-hand expression i.e. the enum could be serialized to the same format (string) for fast comparison on the database side.
Is there a workaround to ensure the serializer is respected in LINQ queries?
Can I register the serializer in a different way so that LINQ v3 applies it?
Share Improve this question edited 7 hours ago SJFJ asked yesterday SJFJSJFJ 6776 silver badges19 bronze badges1 Answer
Reset to default 0If you do not use a custom serializer, but store the value as string by applying the BsonRepresentation
attribute, the LINQ statement works as expected:
public enum TestEnum
{
Value123 = 123
}
[BsonNoId]
[BsonIgnoreExtraElements]
public class TestDoc
{
[BsonRepresentation(BsonType.String)]
public TestEnum TestAsString { get; set; }
[BsonElement]
public TestEnum TestAsInt => TestAsString;
}
var val123 = await test
.AsQueryable()
.SingleAsync(x => x.TestAsString == TestEnum.Value123);
This leads to the following document stored in the database:
{
"_id": {
"$oid": "67ef9018ea66d16ac7360313"
},
"TestAsString": "Value123",
"TestAsInt": 123
}
本文标签: cMongo linq query ignores custom serialization of linq argument using linq provider v3Stack Overflow
版权声明:本文标题:c# - Mongo linq query ignores custom serialization of linq argument using linq provider v3 - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743785404a2538595.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论