0

I have realized that there are questions that sounds similar to mine but they do not solve my problem. So I want to change a string into a class reference but I cannot change into a variable of type Type, dynamic or anything because then it doesn't work with my generic class.

Please note that the code works when I use a valid class reference. But I have many tables in the DB and it would help a lot if it can be more generic.

Generic class and all works fine here

private class GenericController<T>
        {
            private CoreGradingDBEntities db = new CoreGradingDBEntities();

            public dynamic Get(string Table, string Field, string id)
            {
                dynamic str = db.Database.SqlQuery<T>("SELECT * FROM " + Table + " WHERE " + Field + " = '" + id + "';").ToList();
                return  str;
            }
        }

The method where I am calling the generic class from. When I use a valid class reference it works. So the below code does work.

    [Route("api/Values/Table/Field/id")]
        public dynamic Get(string Table, string Field, string id)
        {
            GenericController<Account> generic = new GenericController<Account>();
            dynamic d = generic.Get(Table, Field, id);
            return d;
        }

What I want to do is replace the Account reference. I have tried this but it changes it into a "variable". The Table parameter is the class reference I want in string form. The below code is wrong but you get the idea of what I want to do.

        [Route("api/Values/Table/Field/id")]
        public dynamic Get(string Table, string Field, string id)
        {
            Type type = Type.GetType(Table); 
            GenericController<type> generic = new GenericController<type>(); //Compiler complaining 
            dynamic d = generic.Get(Table, Field, id);
            return d;
        }

Any help would be much appreciated. Thanks!

Proff_D
  • 41
  • 5

2 Answers2

0

I believe generic type arguments have to be specified at compile time. See this question

If you really want to do this, you will have to resort to reflection

Mike Marshall
  • 7,788
  • 4
  • 39
  • 63
0

I think you cannot use generic in this case. Instead of try this:

private class GenericController
    {
        private CoreGradingDBEntities db = new CoreGradingDBEntities();

        public dynamic Get(string Table, string Field, string id)
        {
            var task = db.Database.SqlQuery(Type.GetType(Table), "SELECT * FROM " + Table + " WHERE " + Field + " = '" + id + "';").ToListAsync();
            dynamic str = task.Result;
            return  str;
        }
    }

then your code may look like this:

        [Route("api/Values/Table/Field/id")]
    public dynamic Get(string Table, string Field, string id)
    {
        GenericController generic = new GenericController();
        dynamic d = generic.Get(Table, Field, id);
        return d;
    }

notice, then d is type of List<object> but since you use dynamic you can call:

dynamic item = d.FirstOrDefault();
var name = item.AccountName;

similiar way as generic

robert
  • 49
  • 3
  • Thanks for the reply. I however receive a null with Type.GetType(Table). If I just return Table I get the correct value passed in by the api request. So I guess the compiler has to know the value at compile time? If nothing else works then I guess I have to check the value of Table string and create an object based on that... – Proff_D Aug 07 '19 at 22:40
  • Type.GetType(Table) returns null if you put incorrect string. Try namespace and class name, divided by dot. see: https://learn.microsoft.com/pl-pl/dotnet/api/system.type.gettype?view=netframework-4.8#System_Type_GetType_System_String_ . – robert Aug 08 '19 at 07:28