EF Core 从方法而不是 属性 中保存值
EF Core save value from method instead of property
我喜欢从方法而不是 属性 向列中添加一些数据。这在 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 个实体。
GetValue()
对于实体 1 returns "I am Entity 1"
GetValue()
对于实体 2 returns "I am Entity 2"
然后我喜欢在Value1
列中存储"I am Entity 1"
和"I am Entity 2"
解决方案
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());
我觉得shadow properties可以帮到你。
EF Core 影子属性允许您定义和保留非域数据,即未在 类 中定义的数据。您在 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}";
}
我喜欢从方法而不是 属性 向列中添加一些数据。这在 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 个实体。
GetValue()
对于实体 1 returns"I am Entity 1"
GetValue()
对于实体 2 returns"I am Entity 2"
然后我喜欢在Value1
"I am Entity 1"
和"I am Entity 2"
解决方案
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());
我觉得shadow properties可以帮到你。
EF Core 影子属性允许您定义和保留非域数据,即未在 类 中定义的数据。您在 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}";
}