Преобразование возвращенного документа из DocumentDB в класс C# со строгой проверкой типов

TEntity — это Generic BaseClass, и есть два класса, производных от BaseClass LocationEntity и ZoneEntity.

Ниже GetById() имеет контекст LocationEntity, но response.Resource возвращает объект ZoneEntity.

      public async Task<TEntity> GetById(string id)
    {
        TEntity readObj = null;
        try
        {
            var response = await client.ReadDocumentAsync(UriFactory.CreateDocumentUri(dbName, collectionName, id),
                requestOptions);
            readObj = (TEntity) (dynamic) response.Resource; // it's ignoring the properties which does not match with TEntity (LocationEntity)
        }
        catch (Exception ex)
        {
            throw ex;
        }
        return readObj;
    }

Как выполнить строгую проверку типов при преобразовании DocumentDB Document в TEntity?

Я хочу создать исключение или что-то в этом роде, когда response.Resource не относится к типу LocationEntity.


person GorvGoyl    schedule 18.04.2017    source источник
comment
ReadDocumentAsync возвращает ResourceResponse<Document>. Я предполагаю, что ваши классы наследуются от Document? Если да, то почему вы не используете общее ограничение для TEntity? В любом случае, этот состав dynamic выглядит неуместно. Разве вы не можете вместо этого использовать конструкцию is TEntity или as TEntity? Также обратите внимание, что throw ex; не сохраняет трассировку стека исключения, а throw; сохраняет.   -  person Pieter Witvoet    schedule 18.04.2017
comment
Я не наследую от Document. Никогда не чувствовал необходимости. readObj = response.Resource, поскольку TEntity дает значение null. Спасибо за информацию об экс.   -  person GorvGoyl    schedule 18.04.2017
comment
Тогда какой документ возвращает ReadDocumentAsync и как вы обычно конвертируете его в LocationEntity? Простое добавление приведения к dynamic, а затем к вашему целевому типу волшебным образом не сработает...   -  person Pieter Witvoet    schedule 18.04.2017
comment
@PieterWitvoet Это происходит. класс, вызывающий этот класс (GetById), передает LocationEntity.   -  person GorvGoyl    schedule 18.04.2017
comment
Я понимаю, что вы называете это GetById<LocationEntity>(...), но я спрашиваю: как бы вы обычно (без дженериков) конвертировали Document в LocationEntity?   -  person Pieter Witvoet    schedule 18.04.2017
comment
см. второй ответ stackoverflow.com/questions/27118998 / Я делаю так LocationEntity location = await _unitOfWork.LocationRepository.GetById(locationId.ToString());   -  person GorvGoyl    schedule 18.04.2017
comment
Ох, хорошо. Таким образом, Document реализует IDynamicMetaObjectProvider, и именно так приведение к dynamic позволяет преобразовать его в любой тип, в который вы хотите. Я не могу найти много информации о том, как должно работать это преобразование, но, по-видимому, оно довольно снисходительно, когда речь идет об отсутствующих или несовпадающих полях. Если нет способа контролировать это поведение, вам, вероятно, придется написать собственный код, чтобы проверить, действительно ли документ содержит все поля, требуемые целевым типом.   -  person Pieter Witvoet    schedule 18.04.2017


Ответы (1)


В итоге я украсил некоторые уникальные свойства LocationEntity свойствами [JsonProperty(Required = Required.Always)] и такими же свойствами ZoneEntity.
Теперь readObj = (TEntity) (dynamic) response.Resource; выдает ошибку, если свойства нет.

Это один из способов, который я понял, но все еще надеюсь на лучший способ.

person GorvGoyl    schedule 18.04.2017