C# ORM中Dto Linq Expression 和 数据库Model Linq Expression之间的转换
今天在百度知道中看到一个问题,研究了一会便回答了:
http://zhidao.baidu.com/question/920461189016484459.html
如何使dto linq 表达式转换到数据库实体对象linq表达式。自己搜集了一些资料然后实战了一下,还是可行。
自己扩展的一个方法 Cast<TInput, TToProperty>(
this
Expression<Func<TInput,
bool
>> expression),代码如下:
namespace System
{
public static class LambdaExpressionExtensions
{
private static Expression Parser(ParameterExpression parameter, Expression expression)
{
if (expression == null) return null;
switch (expression.NodeType)
{
//一元运算符
case ExpressionType.Negate:
case ExpressionType.NegateChecked:
case ExpressionType.Not:
case ExpressionType.Convert:
case ExpressionType.ConvertChecked:
case ExpressionType.ArrayLength:
case ExpressionType.Quote:
case ExpressionType.TypeAs:
{
var unary = expression as UnaryExpression;
var exp = Parser(parameter, unary.Operand);
return Expression.MakeUnary(expression.NodeType, exp, unary.Type, unary.Method);
}
//二元运算符
case ExpressionType.Add:
case ExpressionType.AddChecked:
case ExpressionType.Subtract:
case ExpressionType.SubtractChecked:
case ExpressionType.Multiply:
case ExpressionType.MultiplyChecked:
case ExpressionType.Divide:
case ExpressionType.Modulo:
case ExpressionType.And:
case ExpressionType.AndAlso:
case ExpressionType.Or:
case ExpressionType.OrElse:
case ExpressionType.LessThan:
case ExpressionType.LessThanOrEqual:
case ExpressionType.GreaterThan:
case ExpressionType.GreaterThanOrEqual:
case ExpressionType.Equal:
case ExpressionType.NotEqual:
case ExpressionType.Coalesce:
case ExpressionType.ArrayIndex:
case ExpressionType.RightShift:
case ExpressionType.LeftShift:
case ExpressionType.ExclusiveOr:
{
var binary = expression as BinaryExpression;
var left = Parser(parameter, binary.Left);
var right = Parser(parameter, binary.Right);
var conversion = Parser(parameter, binary.Conversion);
if (binary.NodeType == ExpressionType.Coalesce && binary.Conversion != null)
{
return Expression.Coalesce(left, right, conversion as LambdaExpression);
}
else
{
return Expression.MakeBinary(expression.NodeType, left, right, binary.IsLiftedToNull, binary.Method);
}
}
//其他
case ExpressionType.Call:
{
var call = expression as MethodCallExpression;
List<Expression> arguments = new List<Expression>();
foreach (var argument in call.Arguments)
{
arguments.Add(Parser(parameter, argument));
}
var instance = Parser(parameter, call.Object);
call = Expression.Call(instance, call.Method, arguments);
return call;
}
case ExpressionType.Lambda:
{
var Lambda = expression as LambdaExpression;
return Parser(parameter, Lambda.Body);
}
case ExpressionType.MemberAccess:
{
var memberAccess = expression as MemberExpression;
if (memberAccess.Expression == null)
{
memberAccess = Expression.MakeMemberAccess(null, memberAccess.Member);
}
else
{
var exp = Parser(parameter, memberAccess.Expression);
var member = exp.Type.GetMember(memberAccess.Member.Name).FirstOrDefault();
memberAccess = Expression.MakeMemberAccess(exp, member);
}
return memberAccess;
}
case ExpressionType.Parameter:
return parameter;
case ExpressionType.Constant:
return expression;
case ExpressionType.TypeIs:
{
var typeis = expression as TypeBinaryExpression;
var exp = Parser(parameter, typeis.Expression);
return Expression.TypeIs(exp, typeis.TypeOperand);
}
default:
throw new Exception(string.Format("Unhandled expression type: '{0}'", expression.NodeType));
}
}
public static Expression<Func<TToProperty, bool>> Cast<TInput, TToProperty>(this Expression<Func<TInput, bool>> expression)
{
var p = Expression.Parameter(typeof(TToProperty), "p");
var x = Parser(p, expression);
return Expression.Lambda<Func<TToProperty, bool>>(x, p);
}
}
}
比如有如下的 实体类对象:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
}
简单的测试代码:
class Program
{
static int[] array0 = new[] { , };
static void Main1(string[] args)
{
var array1 = new[] { , };
Expression<Func<UserDto, bool>> exp = null;
Expression<Func<User, bool>> exp2 = null; //====exp====
//exp = u => u.Name == "张三";
//exp = u => u.Id.Equals(1);
//exp = u => u.Id.Equals(1) && u.Name == "张三";
//exp = u => u.Id.Equals(1) && u.Name == "张三" || u.Name == "张三";
//exp = u => Filter(u.Name);
//exp = u => !Filter(u.Name);
//exp = u => u.Id.Equals(1) && u.Name == "张三" && Filter(u.Name);
//exp = u => array1.Contains(u.Id);
//exp = u => array1.Contains(u.Id) || u.Name == "张三";
//exp = u => array0.Contains(u.Id);
//exp = u => u.Id > 0;
//exp = u => u.Id < 10;
//exp = u => u.Id * 2 < 10;
//exp = u => u.Id - 2 < 10;
//exp = u => u.Id + 2 < 10;
//exp = u => u.Id / 2 < 10;
//exp = u => (int)(u.Id / 2) < 10;
//exp = u => u.Name is string;
//exp = u => ((object)u.Id).ToString() == "1";
//exp = u => u.Id == default(int);
//exp = u => true;
//exp = u => Math.Abs(u.Id)==1;
exp = u =>
u.Id.Equals()
&& u.Name == "张三"
&& u.Id <
&& array1.Contains(u.Id)
&& u.Id + <
&& (((object)u.Id).ToString() == "" || u.Name.Contains("三"))
&& Math.Abs(u.Id) ==
&& Filter(u.Name)
&& true
;
//=====exp2=====
exp2 = exp.Cast<UserDto, User>();
Console.WriteLine(exp.ToString());
Console.WriteLine(exp.ToString()); //测试数据
List<User> list = new List<User>() {
new User{ Id=,Name="AAA"},
new User{ Id=,Name="张三"},
new User{ Id=,Name="李四"}
};
var item = list.Where(exp2.Compile()).FirstOrDefault();
Console.WriteLine(item.Name);
Console.ReadKey();
} public static bool Filter(string name)
{
return name.Contains("三");
}
}
应该说常用的筛选条件都是支持的。这里的list由于没有数据库环境就用List<User>模拟的,真实ORM环境换成list.Where(exp2)就可以了。
性能方面没有测试,应该是可以使用缓存的。有兴趣的朋友可以改一下。
C# ORM中Dto Linq Expression 和 数据库Model Linq Expression之间的转换的更多相关文章
- Java 中 byte、byte 数组和 int、long 之间的转换
Java 中 byte 和 int 之间的转换源码: //byte 与 int 的相互转换 public static byte intToByte(int x) { return (byte) x; ...
- java中setDate(Date date)方法和String与Date之间的转换
经常在开发的过程中遇到这样的问题,从数据库中读出来的数据需要转换为对像或者java bean,此时经常使用到setDate(Date date);这样的方法.感觉这是个很简单而又难受的事情,在这里浪费 ...
- C#中的Byte,String,Int,Hex之间的转换函数。
/// <summary> Convert a string of hex digits (ex: E4 CA B2) to a byte array. </summary> ...
- matlab中的reshape快速理解,卷积和乘积之间的转换
reshape: THe convertion between convolution and multiplication:
- java中字节数组byte[]和字符(字符串)之间的转换
转自:http://blog.csdn.net/linlzk/article/details/6566124 Java与其他语言编写的程序进行tcp/ip socket通讯时,通讯内容一般都转换成by ...
- ORM中聚合函数、分组查询、Django开启事务、ORM中常用字段及参数、数据库查询优化
聚合函数 名称 作用 Max() 最大值 Min() 最小值 Sum() 求和 Count() 计数 Avg() 平均值 关键字: aggregate 聚合查询通常都是配合分组一起使用的 关于数据库的 ...
- ORM中的N+1问题
在orm中有一个经典的问题,那就是N+1问题,比如hibernate就有这个问题,这一般都是不可避免的. [N+1问题是怎么出现的] N+1一般出现在一对多查询中,下面以Group和User为例,Gr ...
- VS2017新建MVC+ORM中的LinqDb访问数据库项目
1.前提概述 ORM对象关系映射(Object-Relational Mapping)是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从效果上说,它其实是创建了一个可在编程语言 ...
- 在C#中利用Nuget包使用SQLite数据库和Linq to SQLite
本来是学习在VB中使用SQLite数据库和Linq to SQLite,结果先学习到了在C#中使用SQLite数据库和Linq to SQLite的方法,写出来与大家共同学习.(不知道算不算不务正业) ...
随机推荐
- 在使用 vscode 时 eslint 检测 .vue 文件中的less 部分内容
问题: 在使用 vscode 以及 eslint 来检测 基于 webpack 的 vue-cli 的项目中,eslint 无法检测到 .vue 文件中的less 部分内容. 解答: 1.通过 下载 ...
- Input输入框输入银行卡号自动空格
input输入框是表格中用都最多的,像输入手机,密码,银行卡号的,很多对于输入银行卡号是没有处理的,比如这样~~ 看起来是不是一团乱麻,, 眼睛瞬间一片漆黑~ 如果是这样,会不会好很多呢~~ 其实逻 ...
- document.compatMode属性
document.compatMode用来判断当前浏览器采用的渲染方式. 官方解释: BackCompat:标准兼容模式关闭.CSS1Compat:标准兼容模式开启. 当document.compat ...
- java实现二叉树
栈在遍历的时候不能使用for循环,因为他的size函数在动态变小.
- php 全局变量
参考链接:http://www.cnblogs.com/borage/p/3645285.html
- 一些js
//fixed块随滚动条滚动 window.onscroll=function(){ var scroll_left = $(window).scrollLeft(); $('#table_fixed ...
- Tomcat 内存优化设置
vi /tomcat7.0/bin/catalina.sh 开发环境 #!/bin/sh JAVA_OPTS='-Xms128m -Xmx512m -XX:PermSize=128m' 服务器: #! ...
- 静态界面传值javascript
一:JavaScript静态页面值传递之URL篇能过URL进行传值.把要传递的信息接在URL上.Post.htm 复制代码代码如下: <input type="text" n ...
- .ashx中使用Session
在一般处理程序中给session赋值是报错:未将对象引用设置到对象的实例.
- 【Python网络爬虫二】使用urllib2抓去网页内容
在Python中通过导入urllib2组件,来完成网页的抓取工作.在python3.x中被改为urllib.request. 爬取具体的过程类似于使用程序模拟IE浏览器的功能,把URL作为HTTP请求 ...