EF中如何动态获取泛型EntityTypeBuilder调用自定义WithProjection方法?
解决方案
可以通过反射调用ModelBuilder的泛型Entity<T>()方法,获取对应的泛型EntityTypeBuilder<T>,再反射调用你的WithProjection扩展方法,无需重写适配非类型化对象的版本。
具体实现步骤
- 反射获取
ModelBuilder的无参数泛型Entity方法,以及WithProjection扩展方法的定义。 - 遍历筛选出的所有
ModelBase子类,对每个类型执行:- 构造当前模型类型的泛版
Entity方法,调用后得到泛型EntityTypeBuilder<T>实例。 - 构造对应模型类型的泛版
WithProjection扩展方法,以反射方式调用(扩展方法本质是静态方法,需将EntityTypeBuilder实例作为第一个参数传入)。
- 构造当前模型类型的泛版
代码示例
假设WithProjection扩展方法定义在ModelConfigurationExtensions静态类中:
public static class ModelConfigurationExtensions { public static EntityTypeBuilder<T> WithProjection<T>(this EntityTypeBuilder<T> builder) where T : ModelBase { // 你的投影配置逻辑 return builder; } }
在OnModelCreating中实现自动化调用:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 替换为你筛选出的ModelBase子类集合 var targetModelTypes = Assembly.GetExecutingAssembly().GetTypes() .Where(t => typeof(ModelBase).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface); // 获取ModelBuilder的泛型Entity方法(无参数重载) var entityGenericMethod = typeof(ModelBuilder) .GetMethod(nameof(ModelBuilder.Entity), Type.EmptyTypes); // 获取WithProjection扩展方法 var withProjectionGenericMethod = typeof(ModelConfigurationExtensions) .GetMethod(nameof(ModelConfigurationExtensions.WithProjection)); foreach (var modelType in targetModelTypes) { // 生成针对当前模型类型的泛版Entity方法并调用,得到泛型EntityTypeBuilder var typedEntityMethod = entityGenericMethod.MakeGenericMethod(modelType); var typedEntityBuilder = typedEntityMethod.Invoke(modelBuilder, null); // 生成针对当前模型类型的泛版WithProjection方法并调用 var typedProjectionMethod = withProjectionGenericMethod.MakeGenericMethod(modelType); typedProjectionMethod.Invoke(null, new[] { typedEntityBuilder }); } }
注意事项
- 若
WithProjection有额外参数,需在GetMethod时指定参数类型数组,调用Invoke时传入对应参数值。 - 若存在同名方法重载,需通过
GetMethods配合筛选条件精准定位目标方法。
内容的提问来源于stack exchange,提问作者Randy Hall
相关产品推荐
相关产品推荐

