EF Core сохранить значение из метода вместо свойства - PullRequest
1 голос
/ 16 января 2020

Мне нравится добавлять некоторые данные в столбец из метода, а не из свойства. Возможно ли это как-то в EF Core?

Например, код конфигурации может выглядеть так:

internal class MyEntityTypeConfiguration : IEntityTypeConfiguration<MyEntity>
{
    public void Configure(EntityTypeBuilder<MyEntity> builder)
    {
        builder.ToTable("Table1");

        // Add column "Value1" and set it with the return value of myEntity.GetValue()
        builder.Property<string>("Value1").WithValue(myEntity => myEntity.GetValue()); // TODO create WithValue

        builder.HasKey(o => o.Id);
    }
}

, в этом случае метод WithValue не будет существовать.

Пример:

Например, я сохраню 2 объекта.

  1. GetValue() для возвратов объекта 1 "I am Entity 1"
  2. GetValue() для возвратов объекта 2 "I am Entity 2"

Тогда мне нравится магазин "I am Entity 1" и "I am Entity 2" в столбце Value1

Решение

Решение Jairo с ValueGenerator отлично сработало для меня! Я сделал WithValue так:

internal class ValueRetriever<TEntityEntry, TResult> : Microsoft.EntityFrameworkCore.ValueGeneration.ValueGenerator<TResult>
{
    private readonly Func<TEntityEntry, TResult> _retrieve;

    public ValueRetriever(Func<TEntityEntry, TResult> retrieve)
    {
        _retrieve = retrieve;
    }

    public override bool GeneratesTemporaryValues => false;

    public override TResult Next(EntityEntry entry) => _retrieve((TEntityEntry)entry.Entity);
}

WithValue расширение:

public static void WithValue<TEntityEntry, TResult>(this PropertyBuilder<TResult> propertyBuilder, Func<TEntityEntry, TResult> retrieve)
{
    propertyBuilder.HasValueGenerator((property, type) => new ValueRetriever<TEntityEntry, TResult>(retrieve));
}

Использование:

builder
   .Property<string>("Value1")
   .WithValue<MyEntity, string>(myEntity => myEntity.GetValue()); 

1 Ответ

3 голосов
/ 16 января 2020

Я думаю, теневые свойства могут вам помочь.

EF Базовые теневые свойства позволяют вам определять и сохранять не доменные данные, данные, которые не определены в ваших классах. Вы определяете свойства тени в своем DbContext и используете DbContext для установки их значений.

Чтобы определить их:

modelBuilder.Entity<MyEntity>().Property<String>("Value1");

Чтобы установить их значения:

dbContext.Entry(myEntity).Property("Value1").CurrentValue = myEntity.GetValue();

Кроме того, вы можете использовать метод расширения HasValueGenerator для установки генератора значений, который может получать значение от вашей сущности:

modelBuilder.Entity<MyEntity>().Property<string>("Value1").HasValueGenerator<ValueGenerator>();

Генератор значений:

class ValueGenerator : Microsoft.EntityFrameworkCore.ValueGeneration.ValueGenerator
{
    public override bool GeneratesTemporaryValues => false;

    protected override object NextValue(EntityEntry entry) => ((MyEntity) entry.Entity).GetValue();
}

Сущность:

class MyEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string GetValue() => $"My Name: {Name}";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...