在不了解对象类型(类/表)的情况下查询实体框架实体

Geo*_*ich 5 c# asp.net-mvc entity-framework

我想知道,如果一开始是否有可能,我将如何使用ID和表名来查询数据库(使用EF)。

例如,将函数编写为:

QueryDynamicData(string tableName, long entityID){return GetItem(tableName, entityID);}
Run Code Online (Sandbox Code Playgroud)

可以这样称呼:

var entry = QueryDynamicData("Person", 143);
Run Code Online (Sandbox Code Playgroud)

要澄清的是,这是针对使用实体框架的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;
    }
Run Code Online (Sandbox Code Playgroud)

Ven*_*son 3

是的你可以。有一个来自 ScottGu 的博客

https://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library

(MS 版本的 DynamicLinq https://github.com/kahanu/System.Linq.Dynamic/wiki

其中包含名为 DynamicLinq 的库的 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();
}
Run Code Online (Sandbox Code Playgroud)