Request an Entity Framework object without knowing the type of object (class / table) in advance

I am wondering if this is possible in the first place, how I will access the database (using EF) using the identifier and name of the table.

For example, writing a function as:

QueryDynamicData(string tableName, long entityID){return GetItem(tableName, entityID);}

And can be called as:

var entry = QueryDynamicData("Person", 143);

To clarify, this is for an ASP.Net MVC project using Entity Frameworks.

Thanks in advance!

EDIT:

Following @JPVenson's example, I came up with the following code. Please note that it returns a list of dictionaries, although the identifier is unique, as I think in advance when we want to get all the results for a dynamic table, and not just using Id. (This is only a proof of concept level)

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;
    }
+4
source share
2 answers

, . 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)

wiki lib DynamicLinq. , .

, 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();
}
+2

, , ( 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);
}

, , ( ) .

0

Source: https://habr.com/ru/post/1685903/


All Articles