我需要从mi DbContext获取所有TEntity来从每个表中提取所有信息。我有一些信息很少的桌子。 我有这个代码但是没有用。
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获取属性。我使用它来获取我的DbContext中的所有DbSet
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;
}
答案 0 :(得分:2)
我不确定您当前的路径是否是解决更大问题的最佳方法(实现数据库同步器)。但这是解决您较小问题的方法(调用您的通用代码)。
创建泛型类,使用反射创建实例,而不是扩展方法。此外,添加一个接口以与实例通信。请记住,该类可能是通用的,但如果您必须从非泛型代码与它进行对话,那么您需要一个接口来从泛型类实例转换为非泛型接口实例(如果您知道我的意思)。
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);
}
注意:我没有对此进行过测试,但我已多次使用该原理。