程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 通過反射調用泛型參數方法

通過反射調用泛型參數方法

編輯:C#入門知識

最近在學習EDM,發現LinqPad是一個好東西,可以運行Linq To Sql, Entity SQL Language腳本,但不會用ESql查詢功能,始終報錯,半天找不到門道,一怒之下決定自己寫一個小型的ESql查詢器。

 

將比較重要的知識點歸納了一下,貼幾段重要的代碼,以免下次遺忘。

 

        private void btnRunQuery_Click(object sender, EventArgs e)
        {
            if (cmbEntitySet.SelectedItem == null)
                return;
            Type typeObjectQuery = (cmbEntitySet.SelectedItem as ImageComboBoxItem).Value as Type;
            Type typeEntity = typeObjectQuery.GetGenericArguments()[0];

            using (cdms3Entities ctx = new cdms3Entities())
            {
                //通過反射調用ObjectQuery<T> CreateQuery<T>(string queryString, params ObjectParameter[] parameters);
                MethodInfo miCreateQuery = ctx.GetType().GetMethod("CreateQuery", BindingFlags.Instance | BindingFlags.Public);
                //設置CreateQuery<T>中的T泛型參數為typeEntity所指的實體對象類型
                miCreateQuery = miCreateQuery.MakeGenericMethod(typeEntity);
                //創建調用參數,傳入Entity SQL Language語句
                object[] args = new object[] { mmeESql.Text, new ObjectParameter[] { } };
                //調用CreateQuery函數,返回一個ObjectQuery<T>類型的對象,ObjectQuery<T>泛型類由ObjectQuery類派生,所以可轉換為ObjectQuery類型
                ObjectQuery oq = miCreateQuery.Invoke(ctx, args) as ObjectQuery;

                //如果下列檢查框中有選擇需要Include到查詢中的實體對象
                if (cmbIncludes.Properties.GetCheckedItems() != "")
                {
                    //獲取ObjectQuery<T> Include(string path);函數,注意函數的返回值類型是泛型,但函數並不是泛型,所以不需要也不能對其調用MakeGenericMethod方法
                    MethodInfo miInclude = oq.GetType().GetMethod("Include", BindingFlags.Instance | BindingFlags.Public);
                    foreach (CheckedListBoxItem item in cmbIncludes.Properties.Items)
                    {
                        if (item.CheckState == CheckState.Checked)
                        {
                            EntityObjectInfo eo = item.Value as EntityObjectInfo;
                            args = new object[] { eo.Path };
                            //調用ObjectQuery<T>.Include方法
                            oq = miInclude.Invoke(oq, args) as ObjectQuery;
                        }
                    }
                }

                //下面調用ObjectQuery<T>.ToList()方法來獲取查詢結果。
                //特別要注意的是ToList()方法是一個擴展方法,方法原型是:public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source);位於System.Linq.Enumerable類
                //所以反射時應當對Enumerable類進行,且該方法為公共靜態方法。
                MethodInfo miToList = typeof(Enumerable).GetMethod("ToList", BindingFlags.Static | BindingFlags.Public);
                miToList = miToList.MakeGenericMethod(typeEntity);
                args = new object[] { oq };
                object o = miToList.Invoke(null, args);
                //var q = ctx.CreateQuery<Department>(mmeESql.Text);
                mmeTraceSql.Text = oq.ToTraceString();
                grdResultData.DataSource = o;
            }

        }
 

 

    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved