猿问

动态查找 CRUD 操作的实际 DbSet

我在此站点上进行了搜索,但无法从我的上下文中获取实际的 DbSet。我正在尝试根据表名动态检索每个数据库集。


 var dynamicdbset = GetDbSetByTableName(uploadTableName); //Dbset name is Mytables



  private dynamic GetDbSetByTableName(string tableName)

        {

            MyEntities context = new MyEntities();

            System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();

            var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");


            using (var db = new MyEntities())

            {

                var dbset = prop?.GetValue(db);

                return dbset;

            }


        }

这里的问题是它返回了一些通用数据库集,但我不能使用 linq 也不能做一个简单的操作,比如


dynamicdbset.Where(t = > t.Id == 123).Single();

我需要能够通过 tablename 动态获取 dbset,并且还需要以与创建数据相同的方式查询数据


var value = context.MyTables.FirstorDefault()


红颜莎娜
浏览 149回答 1
1回答

神不在的星期二

返回的动态DbSet实际上只是真实DbSet对象的包装器,您可以简单地将其转换为。然而,问题是,如果不使用泛型方法DbSet,就无法推断出的类型。以下方法可行,但可能是最不可取的:private IEnumerable<T> GetDbSetByTableName<T>(string tableName){&nbsp; &nbsp; System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();&nbsp; &nbsp; var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");&nbsp; &nbsp; using (var db = new ClearGUIEntities())&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var dbset = prop?.GetValue(db);&nbsp; &nbsp; &nbsp; &nbsp; return new List<T>(dbset as IEnumerable<T>);&nbsp; &nbsp; }}现在,要解决这个问题,我们至少有两个选择:DbSet创建一个由所有s实现的接口(具有您需要的所有基本属性) 。这样,我们可以转换动态对象,而无需在转换时指定类型。返回一个IEnumerable<dynamic>可以即时施放的。选项1public interface IBaseProperties{&nbsp; &nbsp; int Id { get; set; }&nbsp; &nbsp; string Name { get; set; }}public class MyTable : IBaseProperties{&nbsp; &nbsp; // Add these with either T4 templates or create partial class for each of these entities&nbsp; &nbsp; public int Id { get; set; }&nbsp; &nbsp; public string Name { get; set; }}private IEnumerable<IBaseProperties> GetDbSetByTableName(string tableName){&nbsp; &nbsp; System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();&nbsp; &nbsp; var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");&nbsp; &nbsp; using (var db = new ClearGUIEntities())&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var dbset = prop?.GetValue(db);&nbsp; &nbsp; &nbsp; &nbsp; return new List<IBaseProperties>(dbset as IEnumerable<IBaseProperties>);&nbsp; &nbsp; }}// ...// Using it// ...var dynamicdbset = GetDbSetByTableName("MyTable");int id = dynamicdbset.FirstOrDefault().Id;选项 2private IEnumerable<dynamic> GetDbSetByTableName(string tableName){&nbsp; &nbsp; System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();&nbsp; &nbsp; var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");&nbsp; &nbsp; using (var db = new ClearGUIEntities())&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var dbset = prop?.GetValue(db);&nbsp; &nbsp; &nbsp; &nbsp; return new List<dynamic>(dbset as IEnumerable<dynamic>);&nbsp; &nbsp; }}// ...// At this point, you can basically access any property of this entity// at the cost of type-safetystring id = dynamicdbset.FirstOrDefault().Id;string name = dynamicdbset.FirstOrDefault().Name;顺便说一句,强制转换List<T>是必要的,因为您使用的是using块之外的对象,此时它将被处置。new List<IBaseProperties>(dbset as IEnumerable<IBaseProperties>);
随时随地看视频慕课网APP
我要回答