我在C#中有一个ProductDiscount类。其他类继承自它(FlatDiscount,PercentageDiscount等)。
在Elastic中存储数据似乎可行,但我无法从Elastic中读取数据。
我收到此错误: 无法创建类型为ProductDiscount的实例。类型是接口或抽象类,无法实例化。路径“折扣金额”,第1行,位置1098。
当我查看索引时,折扣确实是集合中的storef,但是没有指示类的类型。
是否可以使用巢式客户端在c#中映射抽象属性?
我尝试使用此映射描述符,但没有成功:
mappingsDescriptor.Map<Product>(x => x
.Properties(props => props
.Object<ProductDiscount>(o => o.Name(prop => prop.Discount))
.Object<FlatProductDiscount>(o => o.Name(prop => prop.Discount).AutoMap())
.Object<PercentageProductDiscount>(o => o.Name(prop => prop.Discount).AutoMap())
.Object<FreeProductProductDiscount>(o => o.Name(prop => prop.Discount).AutoMap())
.Object<QuantityProductDiscount>(o => o.Name(prop => prop.Discount).AutoMap())
)
);
使用ElasticClient进行读取:
var result = await ElasticClient.SearchAsync<Product>(new SearchRequest(Indices.Index(index: CollectionName)));
答案 0 :(得分:1)
我找到了解决方法!
我使用JsonSubTypes package编写了一个自定义转换器。
private static JsonConverter DiscountConverter()
{
var assembly = Assembly.GetAssembly(typeof(ProductDiscount));
var builder = JsonSubtypesConverterBuilder
.Of(typeof(ProductDiscount), "Type");
assembly
.GetTypes()
.Where(type => type.IsSubclassOf(typeof(ProductDiscount)) && !type.IsAbstract)
.ForEach(s =>
{
builder.RegisterSubtype(s, s.Name);
});
var converter = builder
.SerializeDiscriminatorProperty()
.Build();
return converter;
}
我的连接是这样建立的
var pool = new SingleNodeConnectionPool(new Uri(uris.First()));
connectionSettings = new ConnectionSettings(pool, connection, SourceSerializer());
private static ConnectionSettings.SourceSerializerFactory SourceSerializer()
{
return (builtin, settings) => new JsonNetSerializer(builtin, settings,
() => new JsonSerializerSettings
{
Converters = new List<JsonConverter>
{
new StringEnumConverter(),
DiscountConverter()
}
});
}