Как изменить EntityState для свойства с преобразованием значения? - PullRequest
0 голосов
/ 12 февраля 2019

Я использую ValueConverter для сопоставления пользовательского типа свойства (List) со строкой.Преобразование работает отлично, но я не могу установить EntityState на измененный, потому что EF не находит сущность.

Когда я изменяю список, EF не обнаруживает изменения, которые являются уязвимыми.Однако, когда я пытаюсь изменить состояние вручную, я получаю ошибку

The entity type 'List<List<Reward>>' was not found. Ensure that the entity type has been added to the model.

Единственный найденный мной обходной путь - установить свойство клонировать список, что не идеально.

model.PropertyName = new List<Reward>(model.PropertyName); // clone the list

Вот пример кода:

public class RewardContainer
{
    public List<List<Reward>> Rewards { get; set; }
}

// db context
protected override void OnModelCreating(ModelBuilder builder)
{
    // use custom conversion, which is working fine
    builder.Entity<RewardContainer>().Property(p => p.Rewards).HasConversion(ValueConverters.GetJsonConverter<List<List<Reward>>>());
}

// controller
public async Task ModifyProperty()
{
    rewardContainer.Rewards[0].Add(someReward);

    // try to manually change the EntityState...
    dbContext.Entry(rewardContainer.Rewards).State = EntityState.Modified;
    // error: The entity type 'List<List<Reward>>' was not found. Ensure that the entity type has been added to the model.        

    await dbContext.SaveChangesAsync();
}

1 Ответ

0 голосов
/ 14 февраля 2019

Использование ValueComprarer в дополнение к ValueConverter позволяет EF отслеживать преобразованный объект.

public static class ValueConversionExtensions
{
    public static PropertyBuilder<T> HasJsonConversion<T>(this PropertyBuilder<T> propertyBuilder) where T : class, new()
    {
        ValueConverter<T, string> converter = new ValueConverter<T, string>
        (
            v => JsonConvert.SerializeObject(v),
            v => JsonConvert.DeserializeObject<T>(v) ?? new T()
        );

        ValueComparer<T> comparer = new ValueComparer<T>
        (
            (l, r) => JsonConvert.SerializeObject(l) == JsonConvert.SerializeObject(r),
            v => v == null ? 0 : JsonConvert.SerializeObject(v).GetHashCode(),
            v => JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(v))
        );

        propertyBuilder.HasConversion(converter);
        propertyBuilder.Metadata.SetValueConverter(converter);
        propertyBuilder.Metadata.SetValueComparer(comparer);

        return propertyBuilder;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...