C# 如何通过名称获得TEntity
我需要从mi DbContext中获取所有tentity,以从每个表中提取所有信息。我有一些资料很少的小桌子。 我有这个代码,但不工作C# 如何通过名称获得TEntity,c#,entity-framework,C#,Entity Framework,我需要从mi DbContext中获取所有tentity,以从每个表中提取所有信息。我有一些资料很少的小桌子。 我有这个代码,但不工作 var dbSetPropertiesLocal = local.GetDbSetProperties(); foreach (var item in dbSetPropertiesLocal) { Type type = item.PropertyType; // This need get the type of t
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);
}
var dbSetPropertiesLocal=local.GetDbSetProperties();
foreach(dbSetPropertiesLocal中的var项目)
{
Type Type=item.PropertyType;//这需要获取实际数量的类型
var enumerable=GetLocal(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();
}
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 List GetLocal(字符串名,DbContext-ctx)
{
var enumerable=(IEnumerable)(typeof([ClassNameOfMyContext]).GetProperty(name).GetValue(ctx,null));
返回可枚举的.ToList();
}
此方法从my DbContext获取属性。我使用它来获取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();
}
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;
}
publicstaticlist GetDbSetProperties(此DbContext上下文)
{
var dbSetProperties=new List();
var properties=context.GetType().GetProperties();
foreach(属性中的var属性)
{
var setType=property.PropertyType;
var isDbSet=setType.IsGenericType&(typeof(IDbSet).IsAssignableFrom(setType.GetGenericTypeDefinition())| | setType.GetInterface(typeof(IDbSet.FullName)!=null);
if(isDbSet)
添加(属性);
}
归还资产;
}
我不确定当前路径是否是解决更大问题的最佳方法(实现数据库同步器)。但这里有一个小问题的解决方案(调用泛型代码)
创建泛型类,并使用反射创建实例,而不是扩展方法。另外,添加一个与实例对话的接口。记住,类可能是泛型的,但是如果您必须从非泛型代码与它对话,那么您需要一个接口来将泛型类实例转换为非泛型接口实例(如果您知道我的意思的话)
公共接口ILocalEntityListProvider{
List GetLocal(字符串名,DbContext-ctx);
}
公共类LocalEntityListProvider:ILocalEntityListProvider{
私有IEnumerable GetLocal(字符串名,DbContext ctx)
{
return(IEnumerable)(typeof([ClassNameOfMyContext])
.GetProperty(名称)
.GetValue(ctx,null));
}
列表ILocalEntityListProvider.GetLocal(字符串名,DbContext ctx){
返回GetLocal(名称,ctx)
.Cast()
.ToList();
}
}
var dbSetPropertiesLocal=local.GetDbSetProperties();
foreach(dbSetPropertiesLocal中的var项目)
{
var entityType=item.PropertyType.GenericTypeArguments.First();
var providerClassType=typeof(LocalEntityListProvider)。MakeGeneric(entityType);
var providerInstance=Activator.CreateInstance(providerClassType)作为ILocalEntityListProvider;
var enumerable=providerInstance.GetLocal(item.Name,local);
}
注意:我没有测试过这一点,但我已经多次使用了这一原理。我不确定当前路径是否是解决更大问题的最佳方法(实现数据库同步器)。但这里有一个小问题的解决方案(调用泛型代码) 创建泛型类,并使用反射创建实例,而不是扩展方法。另外,添加一个与实例对话的接口。记住,类可能是泛型的,但是如果您必须从非泛型代码与它对话,那么您需要一个接口来将泛型类实例转换为非泛型接口实例(如果您知道我的意思的话) 公共接口ILocalEntityListProvider{ List GetLocal(字符串名,DbContext-ctx); } 公共类LocalEntityListProvider:ILocalEntityListProvider{ 私有IEnumerable GetLocal(字符串名,DbContext ctx) { return(IEnumerable)(typeof([ClassNameOfMyContext]) .GetProperty(名称) .GetValue(ctx,null)); } 列表ILocalEntityListProvider.GetLocal(字符串名,DbContext ctx){ 返回GetLocal(名称,ctx) .Cast() .ToList(); } } var dbSetPropertiesLocal=local.GetDbSetProperties(); foreach(dbSetPropertiesLocal中的var项目) { var entityType=item.PropertyType.GenericTypeArguments.First(); var providerClassType=typeof(LocalEntityListProvider)。MakeGeneric(entityType); var providerInstance=Activator.CreateInstance(providerClassType)作为ILocalEntityListProvider; var enumerable=providerInstance.GetLocal(item.Name,local); }
注意:我没有对此进行测试,但我已经多次使用了该原理。此代码的目的是从dbcontext中的每个实体获取所有数据?是的,我正在进行数据库同步。使用
context.Set().ToList()不是容易多了吗
类似于context.Set().ToList()
,但我不知道我的DbContext中有多少个实体,所以我需要做泛型。你能使用第三方库吗,还是有限制?当您添加TPC、TPH和TPT继承时,查找所有表/属性可能有点困难。此代码的目的是从dbcontext中的每个实体获取所有数据?是的,我正在进行数据库同步。仅仅使用context.Set().ToList()不是容易得多吗
类似于context.Set().ToList()
,但我不知道我的DbContext中有多少个实体,所以我需要做泛型。你能使用第三方库吗,还是有限制?添加TPC、TPH和TPT继承时,查找所有表/属性可能有点困难。“Type不包含“Make Generic”的定义,也没有接受类型为“Type”的第一个参数的扩展方法。它应该是Type.MakeGenericType。我稍后会修复它。我尝试使用您的解决方案,并引发以下错误:您无法将“System.Data.Entity.DbSet1[myEntity]”类型的对象转换为“System.Collections.Generic.IEnumerable
1[System.Data.En