EF经验分享_jimmyzzc
刚刚接触EF,总结了一些在实际工作中的心德经验,与大家分享一下。
一、Excression表达式树
表达式目录树在LINQ中用于表示分配给类型为Expression<TDelegate>的变量的Lambda表达式。还可用于创建动态LINQ查询。
System.Linq.Expressions命名空间提供用于手动生成表达式目录树的API。Expression类包含创建特定类型的表达式目录树节点的静态工厂方法,例如,ParameterExpression(表示一个已命名的参数表达式)或 MethodCallExpression(表示一个方法调用)。编译器生成的表达式目录树的根始终在类型Expression<TDelegate>的节点中,其中TDelegate是包含至多五个输入参数的任何TDelegate委托;也就是说,其根节点是表示一个lambda表达式。
以下例子是EF3.5中运行的,相同的代码在VS2008 EF3.5中是可以正常运行的。在4.5中会抛如下异常。
纠结万分后找到解决方法,代码如下:
1 IQueryable<Person集> custs = db.Person集; 2 3 //创建一个参数c 4 5 ParameterExpression param = 6 7 Expression.Parameter(typeof(Person集), "c"); 8 9 Expression left = Expression.Property(param, 10 11 typeof(Person集).GetProperty("Age")); 12 13 Expression right = Expression.Constant(30); 14 15 Expression filter = Expression.Equal(left, right); 16 17 //Expression pred = Expression.Lambda(filter, param); 18 19 ////Where(c=>c.City=="London") 20 21 //Expression expr = Expression.Call(typeof(Queryable), "Where", 22 23 // new Type[] { typeof(Person集) }, 24 25 // Expression.Constant(custs), pred); 26 27 ////生成动态查询 28 29 //IQueryable<Person集> query = db.Person集.AsQueryable() 30 31 // .Provider.CreateQuery<Person集>(expr); 32 33 var result = db.Person集.Where(Expression.Lambda<Func<Person集, bool>>(filter, param));
通过实体的导航属性的字段的条件过滤,动态生成多个查询条件并带有导航属性
1 IQueryable<Position集> cities = db.Position集; 2 3 ParameterExpression param = Expression.Parameter(typeof(Position集), "c"); 4 5 Expression left = Expression.Property(param, typeof(Position集).GetProperty("Person集")); //先得到导航属性Person集 6 7 Expression leftproperty = Expression.Property(left, "age"); //再得到Person集.Name 8 9 Expression right = Expression.Constant(30); 10 11 Expression filter = Expression.Equal(leftproperty, right); 12 13 14 15 left = Expression.Property(param, typeof(Position集).GetProperty("Company集")); 16 17 leftproperty = Expression.Property(left, "Telephone"); 18 19 right=Expression.Constant("77777777"); 20 21 Expression filter1 = Expression.Equal(leftproperty, right); 22 23 var result = db.Position集.Where(Expression.Lambda<Func<Position集, bool>>(filter, param)) 24 25 .Where(Expression.Lambda<Func<Position集,bool>>(filter1,param));
其实原理很简单,只是根据相应的条件生成多个leftproperty和right就可以了。
以下的各种用法,大家自己对照着修改吧。
1.Select
下面例子说明如何使用表达式树依据 IQueryable 数据源构造一个动态查询,查询出每个顾客的ContactName,并用GetCommand方法获取其生成SQL语句。
1 //依据IQueryable数据源构造一个查询 2 3 IQueryable<Customer> custs = db.Customers; 4 5 //组建一个表达式树来创建一个参数 6 7 ParameterExpression param = 8 9 Expression.Parameter(typeof(Customer), "c"); 10 11 //组建表达式树:c.ContactName 12 13 Expression selector = Expression.Property(param, 14 15 typeof(Customer).GetProperty("ContactName")); 16 17 Expression pred = Expression.Lambda(selector, param); 18 19 //组建表达式树:Select(c=>c.ContactName) 20 21 Expression expr = Expression.Call(typeof(Queryable), "Select", 22 23 new Type[] { typeof(Customer), typeof(string) }, 24 25 Expression.Constant(custs), pred); 26 27 //使用表达式树来生成动态查询 28 29 IQueryable<string> query = db.Customers.AsQueryable() 30 31 .Provider.CreateQuery<string>(expr); 32 33 //使用GetCommand方法获取SQL语句 34 35 System.Data.Common.DbCommand cmd = db.GetCommand(query); 36 37 Console.WriteLine(cmd.CommandText);
生成的SQL语句为:
1 SELECT [t0].[ContactName] FROM [dbo].[Customers] AS [t0]
2.Where
下面一个例子是“搭建”Where用法来动态查询城市在伦敦的顾客。
1 IQueryable<Customer> custs = db.Customers; 2 3 //创建一个参数c 4 5 ParameterExpression param = 6 7 Expression.Parameter(typeof(Customer), "c"); 8 9 //c.City=="London" 10 11 Expression left = Expression.Property(param, 12 13 typeof(Customer).GetProperty("City")); 14 15 Expression right = Expression.Constant("London"); 16 17 Expression filter = Expression.Equal(left, right); 18 19 20 21 Expression pred = Expression.Lambda(filter, param); 22 23 //Where(c=>c.City=="London") 24 25 Expression expr = Expression.Call(typeof(Queryable), "Where", 26 27 new Type[] { typeof(Customer) }, 28 29 Expression.Constant(custs), pred);
生成动态查询
1 IQueryable<Customer> query = db.Customers.AsQueryable() 2 3 .Provider.CreateQuery<Customer>(expr); 4 5 生成的SQL语句为: 6 7 8 SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], 9 10 [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], 11 12 [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax] 13 14 FROM [dbo].[Customers] AS [t0] WHERE [t0].[City] = @p0 15 16 -- @p0: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London]
3.OrderBy
本例既实现排序功能又实现了过滤功能。
1 IQueryable<Customer> custs = db.Customers; 2 3 //创建一个参数c 4 5 ParameterExpression param = 6 7 Expression.Parameter(typeof(Customer), "c"); 8 9 //c.City=="London" 10 11 Expression left = Expression.Property(param, 12 13 typeof(Customer).GetProperty("City")); 14 15 Expression right = Expression.Constant("London"); 16 17 Expression filter = Expression.Equal(left, right); 18 19 Expression pred = Expression.Lambda(filter, param); 20 21 //Where(c=>c.City=="London") 22 23 MethodCallExpression whereCallExpression = Expression.Call( 24 25 typeof(Queryable), "Where", 26 27 new Type[] { typeof(Customer) }, 28 29 Expression.Constant(custs), pred); 30 31 //OrderBy(ContactName => ContactName) 32 33 MethodCallExpression orderByCallExpression = Expression.Call( 34 35 typeof(Queryable), "OrderBy", 36 37 new Type[] { typeof(Customer), typeof(string) }, 38 39 whereCallExpression, 40 41 Expression.Lambda(Expression.Property 42 43 (param, "ContactName"), param));
生成动态查询
1 IQueryable<Customer> query = db.Customers.AsQueryable() 2 3 .Provider.CreateQuery<Customer>(orderByCallExpression);
下面一张截图显示了怎么动态生成动态查询的过程
生成的SQL语句为:
1 SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], 2 3 [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], 4 5 [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax] 6 7 FROM [dbo].[Customers] AS [t0] WHERE [t0].[City] = @p0 8 9 ORDER BY [t0].[ContactName] 10 11 -- @p0: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London]
4.Union
下面的例子使用表达式树动态查询顾客和雇员同在的城市。
1 //e.City 2 3 IQueryable<Customer> custs = db.Customers; 4 5 ParameterExpression param1 = 6 7 Expression.Parameter(typeof(Customer), "e"); 8 9 Expression left1 = Expression.Property(param1, 10 11 typeof(Customer).GetProperty("City")); 12 13 Expression pred1 = Expression.Lambda(left1, param1); 14 15 //c.City 16 17 IQueryable<Employee> employees = db.Employees; 18 19 ParameterExpression param2 = 20 21 Expression.Parameter(typeof(Employee), "c"); 22 23 Expression left2 = Expression.Property(param2, 24 25 typeof(Employee).GetProperty("City")); 26 27 Expression pred2 = Expression.Lambda(left2, param2); 28 29 //Select(e=>e.City) 30 31 Expression expr1 = Expression.Call(typeof(Queryable), "Select", 32 33 new Type[] { typeof(Customer), typeof(string) }, 34 35 Expression.Constant(custs), pred1); 36 37 //Select(c=>c.City) 38 39 Expression expr2 = Expression.Call(typeof(Queryable), "Select", 40 41 new Type[] { typeof(Employee), typeof(string) }, 42 43 Expression.Constant(employees), pred2); 44 45 //生成动态查询 46 47 IQueryable<string> q1 = db.Customers.AsQueryable() 48 49 .Provider.CreateQuery<string>(expr1); 50 51 IQueryable<string> q2 = db.Employees.AsQueryable() 52 53 .Provider.CreateQuery<string>(expr2);
并集
1 var q3 = q1.Union(q2);
生成的SQL语句为:
1 SELECT [t2].[City] 2 3 FROM ( 4 5 SELECT [t0].[City] FROM [dbo].[Customers] AS [t0] 6 7 UNION 8 9 SELECT [t1].[City] FROM [dbo].[Employees] AS [t1] 10 11 ) AS [t2]
详情见:http://www.cnblogs.com/lyj/archive/2008/03/25/1122157.html
http://blog.csdn.net/going1981/article/details/8003245?reload
二、Dynamic.cs及LinqKit
Dynamic.cs其实也没有什么特殊的奥秘,不过是使用了c#3.0提供的扩展方法,扩展了DynamicQueryable的固有函数。使得where,orderby等可以直接将string作为参数,然后再把传入的字符串进行分析,最终通过System.Linq.Expressions.Expression来实现动态Lambda 。倒是从这里我们可以更好的体会到扩展方法的含义。
在 LINQ 中每一個條件查詢都是用 AND 接起來的,如果要串接 OR 的話必須使用 LINQKit.PredicateBuilder。
假設說用迴圈組合 OR 查詢的話就必須用到 LINQKit,因為沒辦法一行就寫完。
LINQ to SQL 串接 OR 查詢的話就會寫成這樣:
1 var q = from ks in db.Member select ks; 2 3 var predicate = PredicateBuilder.False<Member>(); 4 5 predicate = predicate.Or(x => x.Name.Contains("oo")); 6 7 predicate = predicate.Or(x => x.Name.Contains("pp")); 8 9 //查詢名稱包含"oo"或"pp"的使用者 10 11 q = from ks in q.Where(predicate) 12 13 select ks; 14 15 var model = q.ToList();
但如果要用在 LINQ to Object 時上面那段程式會發生型別錯誤的問題。
這是因為查詢 IQueryable 時 .Where() 裡面接的是 Expression,而查詢 IEnumerable 時要接的是 Func。
因此需要用 .Compile() 將 Expression 轉成 Func 才行。
1 var list = new List<string> { "Microsoft", "Google", "Apple" }; 2 3 var predicate = PredicateBuilder.False<string>(); 4 5 predicate = predicate.Or(x => x.Contains("oo")); 6 7 predicate = predicate.Or(x => x.Contains("pp")); 8 9 var q = from ks in list.Where(predicate.Compile()) 10 11 select ks;
下面是写了注释后的PredicateExtensions,说不清楚构造函数的True和False具体是怎么起作用的,但结果就是我的注释那样,在复合查询写条件时很重要(不过目前全写AND就完成复合查询了,我还没搞多关键词OR的那种)
1 /// <summary> 2 /// 构造函数使用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混合时写在AND后的OR有效 3 /// 构造函数使用False时:单个AND无效,多个AND无效;单个OR有效,多个OR有效;混合时写在OR后面的AND有效 4 /// </summary> 5 public static class PredicateExtensions 6 { 7 public static Expression<Func<T, bool>> True<T>() { return f => true; } 8 9 public static Expression<Func<T, bool>> False<T>() { return f => false; } 10 11 public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2) 12 { 13 var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>()); 14 15 return Expression.Lambda<Func<T, bool>>(Expression.Or(expression1.Body, invokedExpression), expression1.Parameters); 16 } 17 18 public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2) 19 { var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>()); 20 21 return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters); 22 } 23 }
PS:赋上一段自己写的LinqKit代码方便大家参考,以及一些Linq其它知识。
1 public EFTestEntities db = new EFTestEntities(); 2 /// <summary> 3 /// 利用LinqKit类动态生成查询条件 4 /// </summary> 5 /// <returns></returns> 6 public IEnumerable<Person集> 返回人员列表() 7 { 8 //构造函数使用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混合时写在AND后的OR有效 9 //构造函数使用False时:单个AND无效,多个AND无效;单个OR有效,多个OR有效;混合时写在OR后面的AND有效 10 var predicate =PredicateBuilder.True<Person集>(); 11 predicate = predicate.And(p => p.Age > 30 || p.Age < 28); 12 predicate = predicate.And(p => p.Name.Contains("张") || p.Name.Contains("吕")); 13 //与之等效的SQL语句 14 //select * from [dbo].[Person集] 15 //where (Age>30 or Age<28) and (Name like '%张%' or Name like '%吕%') 16 17 var predicate1 = PredicateBuilder.False<Person集>(); 18 predicate1 = predicate1.Or(p => p.Age > 30); 19 predicate1 = predicate1.Or(p => p.Age < 28 && p.Name.Contains("张"));; 20 predicate1 = predicate1.Or(p => p.Name.Contains("吕")); 21 //与之等效的SQL语句 22 //select * from [dbo].[Person集] 23 //where Age>30 or (Age<28 24 //and Name like '%张%') or Name like '%吕%' 25 26 //提供對應至 SQL Server 函式的方法。 只有 LINQ to SQL 查詢才支援 SqlMethods 類別中的方法。 27 //predicate=predicate.Or(p=>SqlMethods.Like(p.Name,"张")); 28 29 //LINQ to SQL 串接 OR 查詢的話就會寫成這樣 30 //var list = db.Person集.Where(predicate); 31 32 //但如果要用在 LINQ to Object 時上面那段程式會發生型別錯誤的問題。错误:LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”。 33 //這是因為查詢 IQueryable 時 .Where() 裡面接的是 Expression,而查詢 IEnumerable 時要接的是 Func。 34 //因此需要用 .Compile() 將 Expression 轉成 Func 才行。 35 var list = db.Person集.Where(predicate.Compile()); 36 var list1 = db.Person集.Where(predicate1.Compile()); 37 38 //追踪生成SQL 39 //System.Linq.Enumerable+WhereEnumerableIterator`1[Demo.Data.Person集] 40 //string sql = list.AsQueryable().ToString(); 41 42 //SELECT [Extent1].[Name] AS [Name]FROM [dbo].[Person集] AS [Extent1] 43 //var result = from p in db.Person集 select p.Name; 44 //string sql = result.AsQueryable().ToString(); 45 46 return list; 47 //return list1; 48 } 49 50 /// <summary> 51 /// 返回的人员及职位_Lambda表达示联合查询(不建议大家用Lambda方式写联合查询,可读性很差,五六个表的话,光打.出来属性就得打好多个.容易蒙圈) 52 /// </summary> 53 /// <returns></returns> 54 public IQueryable 返回Lambda联合查询() 55 { 56 var list = db.Person集.Join(db.Position集, p => p.ID, m => m.Person_ID, (p, m) => new { p, m }) 57 .Join(db.Company集, p => p.m.Company_ID, c => c.ID, (p, c) => new { p, c }) 58 .Where(t => t.p.p.Sex == "0"); 59 return list; 60 }
三、EF查询小技巧
有时我们的实体只需要显示,无需更新,所以为了提高性能,我们不需要实体被EF context追踪。此时可以使用NoTracking的查询来得到实体,这样实体的状态会是Detached(分离式)状态。
1 db.Person集.Where(c => c.Name == "张智超").AsNoTracking();
在使用Entity Framework做查询的时候,如果只需要显示,而不用保存实体,那么可以用AsNoTracking()来获取数据。
这样可以提高查询的性能。 代码如下:
1 var context = new Entities(connectStr); 2 3 var contentlist = context.Set<Content>().AsQueryable().AsNoTracking();
但是如果取到数据后,要对数据做修改并保存,则无法反映到数据库里。 如:
1 var context = new Entities(connectStr); 2 3 var contentlist = context.Set<Content>().AsQueryable().AsNoTracking(); 4 5 var content = contentlist.Where(o => o.Id == 18).FirstOrDefault(); 6 7 content.Id = 19; 8 9 context.SaveChanges();
虽然修改后对数据库进行了Commit,再次读取后发现这条数据的Id还是18。
另外如果对通过AsNoTracking得到的数据做删除处理,则会报错。 如:
1 var context = new Entities(connectStr); 2 3 var contentlist = context.Set<Content>().AsQueryable().AsNoTracking(); 4 5 var content = contentlist.Where(o => o.Id == 18).FirstOrDefault(); context.Set<Content>().Remove(content); 6 7 context.SaveChanges();
执行后会抛出System.InvalidOperationException异常
四、LinqPad功能简介
LINQPAD是一款用于LINQ运算和测试的工具,功能丰富,操作简单。
界面中可大致分为四个分隔窗格:
一、左上部为数据源连接部分,点击添加连接[Addconnection]可以创建一个数据库连接,数据源种类很多,可以添加LinqtoSql,也可以是WCF服务,甚至可以是其它数据源。
二、右边部分就是查询窗口,是写代码LINQ语句、的部分,可以选择写代码的语言与所要查询的数据库,还可以选择数据库查询分析器类似。
三、左下部分是一些教学示例和保存的查询
四、右下部分就是查询结果窗口
五、查询结果窗口的选项卡是很激动人心。(包括:Result,表达式,SQL语句,MSIL代码)
本文使用Customers表中的数据为例,在语言列表中可选择:
1、C#Expression(用于进行LinqSql查询)
from c in Customers select c
2、C#Statement(用于C#语句查询,其中的Dump可以显示查询结果)
var p=from c in Customers select c;
p.Dump();
3、C#Program(用于支持方法和类型的查询,须定义Main方法,此方法中生成的SQL不能看到where查询条件,也不能看到Lambda表达示)
voidMain()
{
var p=from c in Customers select c;
p.Dump();
}
4、SQL查询语句(传统的SQL查询语法)
select * from customer
5、其中在前3种方法中,查询的数据库表默认为表名后面加S,这点在LINQPad中要注意
6、在使用时推荐使用语句模式C#Statement。
六、LinqPad可以添加外部插件引用
点击左上角菜单栏的Query菜单选择Query Properties,或按快捷键F4出现添界面。
选择要添加的DLL文件OK即可。目前只掌握这一项功能,其它的有待研究。
添加成功后可直接用调用其引用文件的方法。(我调用的是支持动态拼接Linq语言的)如下图
结果集如下图:
可查看生成不同的查询语言
1.Lambda表达示
2.SQL语句
3.IL(不太清楚具体的用途)
1 IL_0001: ldarg.0 2 3 IL_0002: call LINQPad.User.TypedDataContext.get_Person闆唖 4 5 IL_0007: call PredicateBuilder.True 6 7 IL_000C: ldtoken LINQPad.User.Person集 8 9 IL_0011: call System.Type.GetTypeFromHandle 10 11 IL_0016: ldstr "p" 12 13 IL_001B: call System.Linq.Expressions.Expression.Parameter 14 15 IL_0020: stloc.0 // CS$0$0000 16 17 IL_0021: ldloc.0 // CS$0$0000 18 19 IL_0022: ldtoken LINQPad.User.Person集.Age 20 21 IL_0027: call System.Reflection.FieldInfo.GetFieldFromHandle 22 23 IL_002C: call System.Linq.Expressions.Expression.Field 24 25 IL_0031: ldc.i4.s 1E 26 27 IL_0033: box System.Int32 28 29 IL_0038: ldtoken System.Int32 30 31 IL_003D: call System.Type.GetTypeFromHandle 32 33 IL_0042: call System.Linq.Expressions.Expression.Constant 34 35 IL_0047: call System.Linq.Expressions.Expression.GreaterThan 36 37 IL_004C: ldloc.0 // CS$0$0000 38 39 IL_004D: ldtoken LINQPad.User.Person集.Age 40 41 IL_0052: call System.Reflection.FieldInfo.GetFieldFromHandle 42 43 IL_0057: call System.Linq.Expressions.Expression.Field 44 45 IL_005C: ldc.i4.s 1C 46 47 IL_005E: box System.Int32 48 49 IL_0063: ldtoken System.Int32 50 51 IL_0068: call System.Type.GetTypeFromHandle 52 53 IL_006D: call System.Linq.Expressions.Expression.Constant 54 55 IL_0072: call System.Linq.Expressions.Expression.LessThan 56 57 IL_0077: call System.Linq.Expressions.Expression.OrElse 58 59 IL_007C: ldc.i4.1 60 61 IL_007D: newarr System.Linq.Expressions.ParameterExpression 62 63 IL_0082: stloc.1 // CS$0$0001 64 65 IL_0083: ldloc.1 // CS$0$0001 66 67 IL_0084: ldc.i4.0 68 69 IL_0085: ldloc.0 // CS$0$0000 70 71 IL_0086: stelem.ref 72 73 IL_0087: ldloc.1 // CS$0$0001 74 75 IL_0088: call System.Linq.Expressions.Expression.Lambda 76 77 IL_008D: call PredicateBuilder.And 78 79 IL_0092: ldtoken LINQPad.User.Person集 80 81 IL_0097: call System.Type.GetTypeFromHandle 82 83 IL_009C: ldstr "p" 84 85 IL_00A1: call System.Linq.Expressions.Expression.Parameter 86 87 IL_00A6: stloc.0 // CS$0$0000 88 89 IL_00A7: ldloc.0 // CS$0$0000 90 91 IL_00A8: ldtoken LINQPad.User.Person集.Name 92 93 IL_00AD: call System.Reflection.FieldInfo.GetFieldFromHandle 94 95 IL_00B2: call System.Linq.Expressions.Expression.Field 96 97 IL_00B7: ldtoken System.String.Contains 98 99 IL_00BC: call System.Reflection.MethodBase.GetMethodFromHandle 100 101 IL_00C1: castclass System.Reflection.MethodInfo 102 103 IL_00C6: ldc.i4.1 104 105 IL_00C7: newarr System.Linq.Expressions.Expression 106 107 IL_00CC: stloc.2 // CS$0$0002 108 109 IL_00CD: ldloc.2 // CS$0$0002 110 111 IL_00CE: ldc.i4.0 112 113 IL_00CF: ldstr "寮�" 114 115 IL_00D4: ldtoken System.String 116 117 IL_00D9: call System.Type.GetTypeFromHandle 118 119 IL_00DE: call System.Linq.Expressions.Expression.Constant 120 121 IL_00E3: stelem.ref 122 123 IL_00E4: ldloc.2 // CS$0$0002 124 125 IL_00E5: call System.Linq.Expressions.Expression.Call 126 127 IL_00EA: ldloc.0 // CS$0$0000 128 129 IL_00EB: ldtoken LINQPad.User.Person集.Name 130 131 IL_00F0: call System.Reflection.FieldInfo.GetFieldFromHandle 132 133 IL_00F5: call System.Linq.Expressions.Expression.Field 134 135 IL_00FA: ldtoken System.String.Contains 136 137 IL_00FF: call System.Reflection.MethodBase.GetMethodFromHandle 138 139 IL_0104: castclass System.Reflection.MethodInfo 140 141 IL_0109: ldc.i4.1 142 143 IL_010A: newarr System.Linq.Expressions.Expression 144 145 IL_010F: stloc.2 // CS$0$0002 146 147 IL_0110: ldloc.2 // CS$0$0002 148 149 IL_0111: ldc.i4.0 150 151 IL_0112: ldstr "鍚�" 152 153 IL_0117: ldtoken System.String 154 155 IL_011C: call System.Type.GetTypeFromHandle 156 157 IL_0121: call System.Linq.Expressions.Expression.Constant 158 159 IL_0126: stelem.ref 160 161 IL_0127: ldloc.2 // CS$0$0002 162 163 IL_0128: call System.Linq.Expressions.Expression.Call 164 165 IL_012D: call System.Linq.Expressions.Expression.OrElse 166 167 IL_0132: ldc.i4.1 168 169 IL_0133: newarr System.Linq.Expressions.ParameterExpression 170 171 IL_0138: stloc.1 // CS$0$0001 172 173 IL_0139: ldloc.1 // CS$0$0001 174 175 IL_013A: ldc.i4.0 176 177 IL_013B: ldloc.0 // CS$0$0000 178 179 IL_013C: stelem.ref 180 181 IL_013D: ldloc.1 // CS$0$0001 182 183 IL_013E: call System.Linq.Expressions.Expression.Lambda 184 185 IL_0143: call PredicateBuilder.And 186 187 IL_0148: call System.Linq.Queryable.Where 188 189 IL_014D: call LINQPad.Extensions.Dump
posted on 2014-05-12 14:32 shanheblog 阅读(611) 评论(3) 编辑 收藏 举报