如何按名称获取 TEntity
本文关键字:TEntity 获取 何按名 | 更新日期: 2023-09-27 18:33:21
我需要从mi DbContext获取所有TEntitys,以从每个表中提取所有信息。我有小表格,信息很少。我有这个代码,但不起作用。
var dbSetPropertiesLocal = local.GetDbSetProperties();
foreach (var item in dbSetPropertiesLocal)
{
Type type = item.PropertyType; // This need get the type of the actual TEntity
var enumerable = GetLocal<type>(item.Name, local);
}
此方法按名称和指定的 DbContext 返回指定 DbSet 中的所有数据
public List<TEntity> GetLocal<TEntity>(string name, DbContext ctx)
{
var enumerable = (IEnumerable<TEntity>)(typeof([ClassNameOfMyContext]).GetProperty(name).GetValue(ctx, null));
return enumerable.ToList();
}
此方法从我的 DbContext 中获取属性。我用它来获取我的数据库上下文中的所有数据库集
public static List<PropertyInfo> GetDbSetProperties(this DbContext context)
{
var dbSetProperties = new List<PropertyInfo>();
var properties = context.GetType().GetProperties();
foreach (var property in properties)
{
var setType = property.PropertyType;
var isDbSet = setType.IsGenericType && (typeof(IDbSet<>).IsAssignableFrom(setType.GetGenericTypeDefinition()) || setType.GetInterface(typeof(IDbSet<>).FullName) != null);
if (isDbSet)
dbSetProperties.Add(property);
}
return dbSetProperties;
}
我不确定您当前的路径是否是解决更大问题(实现数据库同步器)的最佳方法。但这里有一个解决方案来解决你的小问题(调用你的通用代码)。
而不是扩展方法,创建一个泛型类,并使用反射创建一个实例。此外,添加一个接口以与实例通信。请记住,该类可能是泛型的,但是如果您必须从非泛型代码与它通信,那么您需要一个接口来从泛型类实例转换为非泛型接口实例(如果您知道我的意思)。
public interface ILocalEntityListProvider {
List<object> GetLocal(string name, DbContext ctx);
}
public class LocalEntityListProvider<TEntity> : ILocalEntityListProvider {
private IEnumerable<TEntity> GetLocal(string name, DbContext ctx)
{
return (IEnumerable<TEntity>)(typeof([ClassNameOfMyContext])
.GetProperty(name)
.GetValue(ctx, null));
}
List<object> ILocalEntityListProvider.GetLocal(string name, DbContext ctx) {
return GetLocal(name, ctx)
.Cast<object>()
.ToList();
}
}
var dbSetPropertiesLocal = local.GetDbSetProperties();
foreach (var item in dbSetPropertiesLocal)
{
var entityType = item.PropertyType.GenericTypeArguments.First();
var providerClassType = typeof(LocalEntityListProvider<>).MakeGeneric(entityType);
var providerInstance = Activator.CreateInstance(providerClassType) as ILocalEntityListProvider;
var enumerable = providerInstance.GetLocal(item.Name, local);
}
注意:我没有测试过这个,但我已经多次使用了这个原理。