我已经在该站点上搜索,无法从上下文中获取实际的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;
}
}
这里的问题是它正在返回一些通用的dbset,但是我不能使用linq,也不能做像这样的简单操作
dynamicdbset.Where(t = > t.Id == 123).Single();
我需要能够通过表名动态获取dbset,并以与我专门创建它的方式相同的方式查询数据
var value = context.MyTables.FirstorDefault()
答案 0 :(得分:1)
返回的动态DbSet
实际上只是实际DbSet
对象的包装,您可以将其简单地转换为对象。但是问题是,如果不使用generic method,就无法推断出DbSet
的类型。
以下方法会起作用,但可能最不推荐:
private IEnumerable<T> GetDbSetByTableName<T>(string tableName)
{
System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();
var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");
using (var db = new ClearGUIEntities())
{
var dbset = prop?.GetValue(db);
return new List<T>(dbset as IEnumerable<T>);
}
}
现在,要解决此问题,我们至少有两个选择:
DbSet
实现的接口(具有所需的所有基本属性)。这样,我们可以在转换时无需指定类型就可以投射动态对象。IEnumerable<dynamic>
,可以即时投放。public interface IBaseProperties
{
int Id { get; set; }
string Name { get; set; }
}
public class MyTable : IBaseProperties
{
// Add these with either T4 templates or create partial class for each of these entities
public int Id { get; set; }
public string Name { get; set; }
}
private IEnumerable<IBaseProperties> GetDbSetByTableName(string tableName)
{
System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();
var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");
using (var db = new ClearGUIEntities())
{
var dbset = prop?.GetValue(db);
return new List<IBaseProperties>(dbset as IEnumerable<IBaseProperties>);
}
}
// ...
// Using it
// ...
var dynamicdbset = GetDbSetByTableName("MyTable");
int id = dynamicdbset.FirstOrDefault().Id;
private IEnumerable<dynamic> GetDbSetByTableName(string tableName)
{
System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();
var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");
using (var db = new ClearGUIEntities())
{
var dbset = prop?.GetValue(db);
return new List<dynamic>(dbset as IEnumerable<dynamic>);
}
}
// ...
// At this point, you can basically access any property of this entity
// at the cost of type-safety
string id = dynamicdbset.FirstOrDefault().Id;
string name = dynamicdbset.FirstOrDefault().Name;
顺便说一句,强制转换为List<T>
是因为您正在使用using
块之外的对象,此时该对象将被处置。
new List<IBaseProperties>(dbset as IEnumerable<IBaseProperties>);