我的类中有以下通用方法,可用作存储库模式:
public DbSet<T> GetAll<T>() where T : class
{
return dbContext.Set<T>();
}
现在,我想获取数据库中属于实现特定接口(IChangeTrackingEntity
)的实体类的所有实体的列表。所以目前大约有 10 个特定的表/类符合这一点,但我不想向这些表添加 10 个硬编码调用,所以我想使用反射来代替(也可能是实现的类这个接口将来会改变,我不想记住在这里也改变并使代码相互依赖)。
有效但我不想要的代码示例:
var result = new List<IChangeTrackingEntity>();
using ( var repository = new DbRepository())
{
result.AddRange( repository.GetAll<FirstTypeThatImplementsInterface>() );
result.AddRange( repository.GetAll<SecondTypeThatImplementsInterface>() );
result.AddRange( repository.GetAll<ThirdTypeThatImplementsInterface>() );
result.AddRange( repository.GetAll<FourthTypeThatImplementsInterface>() );
result.AddRange( repository.GetAll<FifthTypeThatImplementsInterface>() );
}
return result;
我已经很接近了,但是我无法完成将返回结果Invoke
转换为正确类型的最后一部分工作。我目前得到的是这样的:
var result = new List<IChangeTrackingEntity>();
var method = typeof (DbRepository).GetMethod("GetAll");
using ( var repository = new DbRepository())
{
foreach (var p in typeof(AnchorDbContext).GetProperties())
{
if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
{
var pType = p.PropertyType.GetGenericArguments()[0];
if (pType.GetInterface("IChangeTrackingEntity") != null)
{
var genericMethod = method.MakeGenericMethod(new[] {pType});
result.AddRange(genericMethod.Invoke(repository, null) as DbSet<IChangeTrackingEntity>);
}
}
}
return result;
}
上面的问题是 Invoke 调用返回 a object
,我需要将其转换为DbSet<pType>
.
在我当前的代码genericMethod.Invoke(repository, null) as DbSet<IChangeTrackingEntity>
返回null
中,表明我无法根据需要转换返回值,因此我需要特定的返回值类型,而不是我认为的接口。
知道如何做到这一点吗?