简体   繁体   English

Elasticsearch(C#nest):地图抽象属性

[英]Elasticsearch(C# nest): Map abstract property

I have a class ProductDiscount in C#. 我在C#中有一个ProductDiscount类。 Other classes inherit from it (FlatDiscount, PercentageDiscount etc). 其他类继承自它(FlatDiscount,PercentageDiscount等)。

Storing data in Elastic seems to work but I can't read data from Elastic. 在Elastic中存储数据似乎可以正常工作,但是我无法从Elastic中读取数据。

I get this error: Could not create an instance of type ProductDiscount. 我收到此错误:无法创建类型为ProductDiscount的实例。 Type is an interface or abstract class and cannot be instantiated. 类型是接口或抽象类,无法实例化。 Path 'discount.amount', line 1, position 1098. 路径“ discount.amount”,第1行,位置1098。

When I look at my index the discount is indeed storef in the collection but there's no indication of the type of the class. 当我查看索引时,折扣确实是集合中的storef,但是没有指示类的类型。

Is it possible to map an abstract property in c# with the nest client? 是否可以通过巢状客户端在c#中映射抽象属性?

I've tried with this mapping descriptor but with no succes: 我尝试使用此映射描述符,但没有成功:

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())
                 )
            );

Reading is done with the ElasticClient: 阅读是通过ElasticClient完成的:

    var result = await ElasticClient.SearchAsync<Product>(new SearchRequest(Indices.Index(index: CollectionName)));

I found a solution!! 我找到了解决方案!!

I wrote a custom converter using the JsonSubTypes package . 我使用JsonSubTypes包编写了一个自定义转换器。

    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;
    } 

My connection is set up like this 我的连接是这样建立的

            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()
                }
            });
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM