Elasticsearch (C # nest): Карта абстрактного свойства - PullRequest
0 голосов
/ 29 октября 2018

У меня есть класс ProductDiscount в C #. Другие классы наследуются от него (FlatDiscount, PercentageDiscount и т. Д.).

Кажется, что хранение данных в Elastic работает, но я не могу прочитать данные из Elastic.

Я получаю эту ошибку: Не удалось создать экземпляр типа ProductDiscount. Тип является интерфейсом или абстрактным классом и не может быть создан. Путь 'discount.amount', строка 1, позиция 1098.

Когда я смотрю на свой индекс, скидка действительно сохраняется в коллекции, но нет указания на тип класса.

Можно ли отобразить абстрактное свойство в c # с помощью клиента nest?

Я пробовал с этим дескриптором отображения, но безуспешно:

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

1 Ответ

0 голосов
/ 29 октября 2018

Я нашел решение !!

Я написал собственный конвертер, используя пакет 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;
    } 

Мое соединение настроено так

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