上篇我们说到了基于EFCore的基础扩展,这篇我们讲解下基于实体结合拉姆达表达式的自定义更新以及删除数据.
先说下原理:其实通过实体以及拉姆达表达式生成SQL语句去执行
第一种更新扩展:
自定义更新字段以及自定义扩展条件,请看下面的代码1 ///
从上面的方法中我们看到几个参数,第一个参数不必说,扩展方法第一个参数必须要的,我们重点讲清楚一下第二个和第三个参数.
参数:Expression
表示实体中需要更新的字段,这里的参数要求的是一个拉姆达表达式,如下面的代码:
m => m.ClickCount == m.ClickCount + 1
这里就是更新字段ClickCount+1的功能.
参数:Expression
表示更新条件,这个参数也是一个拉姆达表达式,如下面代码:
m => m.NavigationId == navigationId
这里表示更新条件 NavigationId指定值的数据库记录.
接下来我们看方法中的调用TSqlAssembled.Update
这个方法表示将参数解析成SQL语句,我们看看这个方法的具体内容:
1 ///
PS:这个方法中用到的条件编译类以及字段编辑类我们将在文章底部贴出来.
第二种更新扩展:///
参数 TEntity entity表示需要更新的实体
参数 Expression
TSqlAssembled.Update
///
PS:这里我们多了将实体反射获取需要更新的字段以及字段值.
第三种删除扩展:
自定删除条件,代码如下1 ///
参数Expression
dbContext.MangoRemove
PS:此段代码表示根据指定条件删除m_PostsAnswerRecords表中的记录
TSqlAssembled.Delete
下面我们贴出字段以及条件的拉姆达表达式解析类:
条件解析类(ConditionBuilder):1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Text;4 usingSystem.Linq;5 usingSystem.Linq.Expressions;6 usingSystem.Reflection;7 namespaceMango.Framework.EFCore8 {9 public classConditionBuilder : ExpressionVisitor10 {11 12 StringBuilder strBuilder;13 14 publicConditionBuilder()15 {16 }17 18 public stringTranslate(Expression expression)19 {20 this.strBuilder = newStringBuilder();21 this.Visit(expression);22 return this.strBuilder.ToString();23 }24 25 private staticExpression StripQuotes(Expression e)26 {27 while (e.NodeType ==ExpressionType.Quote)28 {29 e =((UnaryExpression)e).Operand;30 }31 returne;32 }33 34 protected overrideExpression VisitBinary(BinaryExpression b)35 {36 strBuilder.Append("(");37 this.Visit(b.Left);38 switch(b.NodeType)39 {40 caseExpressionType.AndAlso:41 strBuilder.Append("and");42 break;43 caseExpressionType.OrElse:44 strBuilder.Append("or");45 break;46 caseExpressionType.Equal:47 strBuilder.Append("=");48 break;49 caseExpressionType.NotEqual:50 strBuilder.Append("<>");51 break;52 caseExpressionType.LessThan:53 strBuilder.Append("<");54 break;55 caseExpressionType.LessThanOrEqual:56 strBuilder.Append("<=");57 break;58 caseExpressionType.GreaterThan:59 strBuilder.Append(">");60 break;61 caseExpressionType.GreaterThanOrEqual:62 strBuilder.Append(">=");63 break;64 default:65 throw new NotSupportedException(string.Format("运算符{0}不支持", b.NodeType));66 }67 if (b.Right.NodeType != ExpressionType.Parameter&& b.Right.NodeType ==ExpressionType.MemberAccess)68 {69 LambdaExpression lambda =Expression.Lambda(b.Right);70 var fn =lambda.Compile();71 this.Visit(Expression.Constant(fn.DynamicInvoke(null), b.Right.Type));72 }73 else 74 {75 this.Visit(b.Right);76 }77 strBuilder.Append(")");78 returnb;79 }80 81 protected overrideExpression VisitConstant(ConstantExpression c)82 {83 switch(Type.GetTypeCode(c.Value.GetType()))84 {85 caseTypeCode.Boolean:86 strBuilder.Append(((bool)c.Value) ? 1 : 0);87 break;88 caseTypeCode.String:89 strBuilder.Append("'");90 strBuilder.Append(c.Value);91 strBuilder.Append("'");92 break;93 caseTypeCode.Object:94 throw new NotSupportedException(string.Format("常量{0}不支持", c.Value));95 default:96 strBuilder.Append(c.Value);97 break;98 }99 returnc;100 }101 102 protected overrideExpression VisitMember(MemberExpression m)103 {104 if (m.Expression != null && m.Expression.NodeType ==ExpressionType.Parameter)105 {106 strBuilder.Append(m.Member.Name);107 returnm;108 }109 else if (m.Expression != null && m.Expression.NodeType ==ExpressionType.Constant)110 {111 LambdaExpression lambda =Expression.Lambda(m);112 var fn =lambda.Compile();113 this.Visit(Expression.Constant(fn.DynamicInvoke(null), m.Type));114 returnm;115 }116 throw new NotSupportedException(string.Format("成员{0}不支持", m.Member.Name));117 }118 }119 }
更新字段解析类(UpdateFieldBuilder):
1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Text;4 usingSystem.Linq;5 usingSystem.Linq.Expressions;6 usingSystem.Reflection;7 namespaceMango.Framework.EFCore8 {9 public classUpdateFieldBuilder : ExpressionVisitor10 {11 StringBuilder strBuilder;12 public stringTranslate(Expression expression)13 {14 this.strBuilder = newStringBuilder();15 this.Visit(expression);16 return this.strBuilder.ToString();17 }18 19 private staticExpression StripQuotes(Expression e)20 {21 while (e.NodeType ==ExpressionType.Quote)22 {23 e =((UnaryExpression)e).Operand;24 }25 returne;26 }27 protected overrideExpression VisitBinary(BinaryExpression b)28 {29 //strBuilder.Append("("); 30 this.Visit(b.Left);31 switch(b.NodeType)32 {33 caseExpressionType.Equal:34 strBuilder.Append("=");35 break;36 caseExpressionType.AndAlso:37 strBuilder.Append(",");38 break;39 caseExpressionType.Add:40 strBuilder.Append("+");41 break;42 caseExpressionType.Subtract:43 strBuilder.Append("-");44 break;45 default:46 throw new NotSupportedException(string.Format("运算符{0}不支持", b.NodeType));47 }48 this.Visit(b.Right);49 //strBuilder.Append(")"); 50 returnb;51 }52 53 protected overrideExpression VisitConstant(ConstantExpression c)54 {55 switch(Type.GetTypeCode(c.Value.GetType()))56 {57 caseTypeCode.Boolean:58 strBuilder.Append(((bool)c.Value) ? 1 : 0);59 break;60 caseTypeCode.String:61 strBuilder.Append("'");62 strBuilder.Append(c.Value);63 strBuilder.Append("'");64 break;65 caseTypeCode.Object:66 throw new NotSupportedException(string.Format("常量{0}不支持", c.Value));67 default:68 strBuilder.Append(c.Value);69 break;70 }71 returnc;72 }73 74 protected overrideExpression VisitMember(MemberExpression m)75 {76 if (m.Expression != null && m.Expression.NodeType ==ExpressionType.Parameter)77 {78 strBuilder.Append(m.Member.Name);79 returnm;80 }81 throw new NotSupportedException(string.Format("成员{0}不支持", m.Member.Name));82 }83 }84 }
到此本篇章完成,更详细的代码请下载源代码查看.