2 回答
![?](http://img1.sycdn.imooc.com/54584eff000195a302200220-100-100.jpg)
TA贡献1802条经验 获得超4个赞
我在这里找到了一些答案:GetEntityTypes: configure entity properties using the generic version of .Property<TEntity> in EF Core
除了上面的评论之外,还有一种方法可以不用为每个实体调用它。这可能可以重构为一些扩展方法,正如 Erndob 在我的问题下的评论所提到的。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
if (typeof(ISoftDeletable).IsAssignableFrom(entityType.ClrType))
{
modelBuilder.Entity(entityType.ClrType).Property<bool>(nameof(ISoftDeletable.IsActive)).HasDefaultValue(true);
}
}
}
解决方案是使用ModelBuilder.Model.GetEntityTypes()和查找可从ISoftDeletable.
在我看来,这比手动配置它甚至创建一个抽象IEntityTypeConfiguration<>类要好得多,因为您不必记住对所有ISoftDeletable类都使用它。
更干净的外观:
public static class ModelBuilderExtensions
{
public static ModelBuilder EntitiesOfType<T>(this ModelBuilder modelBuilder,
Action<EntityTypeBuilder> buildAction) where T : class
{
return modelBuilder.EntitiesOfType(typeof(T), buildAction);
}
public static ModelBuilder EntitiesOfType(this ModelBuilder modelBuilder, Type type,
Action<EntityTypeBuilder> buildAction)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
if (type.IsAssignableFrom(entityType.ClrType))
buildAction(modelBuilder.Entity(entityType.ClrType));
return modelBuilder;
}
}
并且OnModelCreating:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.EntitiesOfType<ISoftDeletable>(builder =>
{
builder.Property<bool>(nameof(ISoftDeletable.IsActive)).HasDefaultValue(true);
// query filters :)
var param = Expression.Parameter(builder.Metadata.ClrType, "p");
var body = Expression.Equal(Expression.Property(param, nameof(ISoftDeletable.IsActive)), Expression.Constant(true));
builder.HasQueryFilter(Expression.Lambda(body, param));
});
}
![?](http://img1.sycdn.imooc.com/545866c40001561502200220-100-100.jpg)
TA贡献1883条经验 获得超3个赞
我想做类似的事情,但使用IEntityTypeConfiguration界面来保存我的通用配置。我最终不得不使用反射,但它有效:
Interface:
public interface IHasDisplayId
{
Guid DisplayId { get; }
}
EntityTypeConfig:
public class HasDisplayIdEntityTypeConfiguration<T> : IEntityTypeConfiguration<T> where T : class, IHasDisplayId
{
public void Configure(EntityTypeBuilder<T> builder)
{
builder.Property(e => e.DisplayId).IsRequired();
builder.HasIndex(e => e.DisplayId);
}
}
Extension method:
public static ModelBuilder ApplyConfiguration<T>(this ModelBuilder modelBuilder, Type configurationType, Type entityType)
{
if (typeof(T).IsAssignableFrom(entityType))
{
// Build IEntityTypeConfiguration type with generic type parameter
var configurationGenericType = configurationType.MakeGenericType(entityType);
// Create an instance of the IEntityTypeConfiguration implementation
var configuration = Activator.CreateInstance(configurationGenericType);
// Get the ApplyConfiguration method of ModelBuilder via reflection
var applyEntityConfigurationMethod = typeof(ModelBuilder)
.GetMethods()
.Single(e => e.Name == nameof(ModelBuilder.ApplyConfiguration)
&& e.ContainsGenericParameters
&& e.GetParameters().SingleOrDefault()?.ParameterType.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>));
// Create a generic ApplyConfiguration method with our entity type
var target = applyEntityConfigurationMethod.MakeGenericMethod(entityType);
// Invoke ApplyConfiguration, passing our IEntityTypeConfiguration instance
target.Invoke(modelBuilder, new[] { configuration });
}
return modelBuilder;
}
Usage:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
modelBuilder.ApplyConfiguration<IHasDisplayId>(typeof(HasDisplayIdEntityTypeConfiguration<>), entityType.ClrType);
}
}
- 2 回答
- 0 关注
- 147 浏览
添加回答
举报