我想知道,如果它首先是可能的话,我将如何使用ID和表名来查询数据库(使用EF)。
例如,将函数编写为:
QueryDynamicData(string tableName, long entityID){return GetItem(tableName, entityID);}
可以这样称呼:
var entry = QueryDynamicData("Person", 143);
为了澄清,这是针对使用实体框架的MVC ASP.Net项目。
提前致谢!
修改
按照@JPVenson的例子,我想出了以下代码。请注意,它返回了一个字典列表,即使Id是唯一的,因为我正在考虑当我们想要获得动态表的所有结果而不仅仅是Id时。 (这只是概念水平的证明)
public List<Dictionary<string, object>> QueryDynamicData(string table, int entityID)
{
try
{
//Get the table desired based on the table name passed
PropertyInfo dbSetInfo = DBContext.GetType().GetProperties().FirstOrDefault(p => p.Name.ToLower().Equals(table.ToLower()));
//Return all results from the table into IQueryable set where Id = entityID passed
IQueryable anyDbSet = ((IQueryable)dbSetInfo.GetValue(DBContext)).Where("Id=" + entityID);
List<Dictionary<string,object>> listObjects = new List<Dictionary<String, Object>>();
//Iterate through results
foreach (Object entity in anyDbSet)
{
//Create dictionary of Field Name, Field Value from results
Dictionary<string, object> listDBValues = entity.GetType().GetProperties().ToDictionary(propertyInfo => propertyInfo.Name, propertyInfo => propertyInfo.GetValue(entity));
//Add dictionary to list of dictionaries - useful for returning list of found results instead of just one
listObjects.Add(listDBValues);
}
//Return list of dictionaries
return listObjects;
}
catch (Exception e) { }
return null;
}
答案 0 :(得分:2)
是的,你可以。 ScottGu有一个博客
https://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library
(DynamicLinq https://github.com/kahanu/System.Linq.Dynamic/wiki的MS版本)
包含名为DynamicLinq的lib的wiki。我目前在项目中使用它,它将适合您的方法。
你仍然必须包装它并使用一些反射来构建一个合适的IQueryable但它为你做了很多工作
编辑代码示例
通过一些反射,您可以像这样访问您的dbSet(未经测试的伪代码!):
public object[] QueryDynamicData(string table, int entityId) {
//Your DbContext that contains all of your
var dbContext = new FooBaa()
//Get the DbSet in your DbContext that matches the "Table" name.
//You are searching for the generic parameter of the DbSet
var dbSetInfo = dbContext.GetType().GetProperties().FirstOrDefault(e => e.GetGenericArguments().Any(f => f.Name.Equals(table));
//Now get the DbSet from the DbContext and cast it to an IQueryabe
IQueryable anyDbSet = (IQueryable)dbSetInfo.GetValue(dbContext);
//Use Dynamic Linq to create a Query that selects an ID
//warning SQL-Injection possible checkout the 2nd argument of type IDictionary
return anyDbSet.Where("Id=" + entityId).ToArray();
}
答案 1 :(得分:0)
我在会议之间有几分钟的时间来处理这个问题,并提出了这个问题(将其添加到DbContext
课程中:
public dynamic FindEntity(string table, long Id)
{
PropertyInfo prop = this.GetType().GetProperty(table, BindingFlags.Instance | BindingFlags.Public);
dynamic dbSet = prop.GetValue(this, null);
return dbSet.Find(Id);
}
它使用一些反射来查找DbContext
上带有表名的属性,并获取对它的引用。然后它在Find
上调用DbSet<T>
以查找具有指定主键的对象。由于您不发送任何实际的Type
信息,因此必须动态输入所有内容。
您可以这样称呼它:
using (var db = new MyContext())
{
var e = db.FindEntity("Animals", 1);
}
我无法保证对您有多大帮助,但 会在我的测试设置中返回(动态输入)数据。