alb*_*mat 5 linq-to-entities dynamic-data auto-generate entity-framework-5
我有一个用实体框架映射的数据库,
我需要实现一个通用方法来根据我传递的参数获取项目列表:
getGenericList("product"); // returns the list of products
getGenericList("customer"); // returns the list of customers
我需要动态获取dbSet. 我的方法是这样实现的:
public static List<object> getGenericList(string entityType)
    {
        List<object> myDynamicList = new List<object>();
        using (cduContext db = new cduContext())
        {
            DbSet dbSet = db.getDBSet(entityType);
            var myDynamicList = dbSet.Select(p => p).ToList();
        }
        return new List<object>();
    }
我dbSets首先由 EF 代码自动生成:
public DbSet<Product> Products { get; set; }
public DbSet<Custommer> Custommers { get; set; }
我的getDBSet(entityType)方法是在上下文中实现的,如下所示:
public DbSet<T> getDBSet<T>(string entityName) where T : class
    {
        switch (entityName)
        {
            case "product":
                return Products;
            case "custommer":
                return Custommers;
然后我得到了这个错误:
无法将类型“System.Data.Entity.DbSet”隐式转换为“System.Data.Entity.DbSet”
请有任何想法!?
NB,该方法Set()的dbContext也不行; 应该明确给出类型......
最好远离字符串作为类型并将它们映射到实际类型;那是代码的味道。相反,使用类型本身。不管怎样,让我们重构使用getGenericList()泛型方法的代码。如果您无法摆脱字符串,请在调用的代码中进行映射getGenericList(),而不是在该方法内部进行映射,因为我们遵循您提出的模式。
另请注意,在原始文件中,getGenericList()您始终返回一个空列表,而不是通过 EF 获取的列表。您还使用了 2 个不同的myDynamicList变量;外部的被语句范围内的掩盖,using这就是为什么你不会得到编译器错误。一旦using超出范围,内部myDynamicList也会超出范围。我已经在这里解决了这个问题。
public static List<T> getGenericList<T>()
{
    List<T> myDynamicList;
    using (cduContext db = new cduContext())
    {
        // consider using exception handling here as GetDbSet might get an invalid type
        DbSet dbSet = db.GetDbSet<T>();
        myDynamicList = dbSet.Select(p => p).ToList();
    }
    if (myDynamicList != null && myDynamicList.Count() > 0)
    {
        return myDynamicList;
    }
    return new List<T>();
}
// in your context class
public DbSet<T> GetDbSet<T>() where T : class
{
    return this.Set<T>();
}
// this is the code that calls getGenericList(); put this inside a function somewhere. 
// entityName holds a string value, set previously
switch(entityName.ToLower()) // making entityName case insensitive
{
    case "product":
        return getGenericList<Product>();
    case "customer":
        return getGenericList<Customer>();
}
希望您不会有太多想要映射的实体类型,否则您最终会得到一个巨大的switch语句。再说一遍,如果您使用switch声明,通常这可能表明您需要重新考虑您的方法。
为了避免switch,您可以通过其程序集限定名称查找类型,然后DbSet从中获取 。通过这种方式检索的 DbSet 不是通用的 <>,因此您可以执行的操作更加有限。
您可以通过使用已知的实体类型(例如Product)获取程序集限定名称,获取其程序集限定名称,然后将“Product”替换为所需名称以获取类型。
此示例是从Breeze应用程序简化而来的,其中可以通过客户端的名称请求某些查找实体。
public async Task<List<object>> GetGenericList(string entityType)
{
  using (var context = new MyContext())
  {
    var aqtemp = typeof(Product).AssemblyQualifiedName; // template for qualified name
    var aqname = aqtemp.Replace("Product", entityType); // qualified name for entityType
    var type = Type.GetType(aqname, true, true);      // Type for entityType
    var list = await context.Set(type).ToListAsync(); // query the entities
    return list;
  }
}
| 归档时间: | 
 | 
| 查看次数: | 12007 次 | 
| 最近记录: |