最近在学习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; } }
以上就是介绍C#通过反射调用泛型参数方法,希望对你有所帮助。 |