mardi 1 juin 2021

C# Pass a type to a DataTable function at runtime

I am using Entity Framework in C#. My database contains the following helper function, which basically converts an IList to a DataTable with whatever entity Type is passed at runtime:

        public static DataTable ToDataTable<T>(this IList<T> data)
        {
            PropertyDescriptorCollection properties =
                TypeDescriptor.GetProperties(typeof(T));
            DataTable table = new DataTable();
            foreach (PropertyDescriptor prop in properties)
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);

            foreach (T item in data)
            {
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                    row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                table.Rows.Add(row);
            }
            return table;
        }

Here is a crude of example of how I need to call this function, lots of times, because there are many combo boxes:

        public bool Custom_EvtManualComboInputAllowed(object combo, ICustomControlType cct, string keyPressed)
        {
            DataTable dt = null;
            ComboBox cmb = (ComboBox)combo;

            if (cct.Name == "IngredientDirection" &&
                (cmb.Name == "CmbIngredientDirectionText" || cmb.Name == "CmbIngredientDirectionType" || cmb.Name == "CmbProteinType"))
            {

                if (cmb.Name == "CmbIngredientDirectionText")
                {
                    _CMainController.DataAccessLayer.SetContext(typeof(IngredientDirectionText));
                    dt = Functions.ToDataTable<IngredientDirectionText>(_CMainController.DataAccessLayer.GetAll());
                }
                else if (cmb.Name == "CmbIngredientDirectionType")
                {
                    _CMainController.DataAccessLayer.SetContext(typeof(IngredientDirectionType));
                    dt = Functions.ToDataTable<IngredientDirectionType>(_CMainController.DataAccessLayer.GetAll());
                }
                else if (cmb.Name == "CmbProteinType")
                {
                    _CMainController.DataAccessLayer.SetContext(typeof(ProteinType));
                    dt = Functions.ToDataTable<ProteinType>(_CMainController.DataAccessLayer.GetAll());
                }

                //Do something with "dt"
            }

            dt = null;
            cmb = null;

            return false; 
        }

I always know that my entity type will be the name of the combox box without "Cmb". Is it possible to use Reflection to extract the type eg. "IngredientDirectionText" or "ProteinType" at runtime and then pass is to the DataTable function? This would greatly reduce the code.

I have searched other questions, but the answers I found seem to all show how to make a Class instance using Reflection, when I simply want to pass the underlying Type. Many thanks in advance.

UPDATED: For clarity

I want to be able to do something like this, but of course this illegal syntax:

        public bool Custom_EvtManualComboInputAllowed(object combo, ICustomControlType cct, string keyPressed)
        {
            DataTable dt = null;
            ComboBox cmb = (ComboBox)combo;

            if (cct.Name == "IngredientDirection" &&
                (cmb.Name == "CmbIngredientDirectionText" || cmb.Name == "CmbIngredientDirectionType" || cmb.Name == "CmbProteinType"))
            {

                string entityName = cmb.Name.Replace("Cmb", "");
                _CMainController.DataAccessLayer.SetContext(typeof(entityName));
                dt = Functions.ToDataTable<entityName>(_CMainController.DataAccessLayer.GetAll());

                //Do something with "dt"
            }

            dt = null;
            cmb = null;

            return false; 
        }




Aucun commentaire:

Enregistrer un commentaire