如何按名称获取 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;
}

如何按名称获取 TEntity

我不确定您当前的路径是否是解决更大问题(实现数据库同步器)的最佳方法。但这里有一个解决方案来解决你的小问题(调用你的通用代码)。

而不是扩展方法,创建一个泛型类,并使用反射创建一个实例。此外,添加一个接口以与实例通信。请记住,该类可能是泛型的,但是如果您必须从非泛型代码与它通信,那么您需要一个接口来从泛型类实例转换为非泛型接口实例(如果您知道我的意思)。

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);  
}

注意:我没有测试过这个,但我已经多次使用了这个原理。