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的方法,写出来与大家共同学习.(不知道算不算不务正业) ...
随机推荐
- jquery1.7.2的源码分析(三)$.Deferred
例子的详细讲解 Filter Resolve var filterResolve = function() { var defer = $.Deferred(), filtered = defer.t ...
- laydate兼容bootstrap
因为Bootstrap使用了 * {box-sizing:border-box;}来reset浏览器的默认盒子模型.所以加上以下代码就可以兼容Bootstrap了 <style type=&qu ...
- Android SDK升级后报错error when loading the sdk 发现了元素 d:skin 开头无效内容
把错误位置的devices.xml这个文件删除,再把sdk里面tools\lib下的这个文件拷贝到你删除的那个文件夹里,重启eclipse
- 【IOS】将字体大小不同的文字底部对齐
从WP转IOS了,还是放不下...... 在项目中,要实现如图多个不同大小的文字 底部对齐的效果 像下面这样: (想要的效果) 以为用三个UIFont不同的UILabel 之后让他们底部对齐 ...
- java程序员快速掌握python系列——概述
这一系列主要是总结学习python过程中的方方面面(已经学完,时间大概是一周左右).当然限于个人水平java也就是够用,python短时间内也不可能深入到哪里去.所以这次的分享的目的是能够快速使用py ...
- juqery 正则表达式的使用
juqery 正则表达式的使用test() 方法用于检测一个字符串是否匹配某个模式.js原生的方法 reg="/^13[0-9]{1}[0-9]{8}$|15[0-9]{1}[0-9]{8} ...
- php php-5.6.4.tar.bz2 apache 兼容问题 child pid 27858 exit signal Segmentation fault
环境 [root envirotar]# uname -a Linux i2..el6.x86_64 # SMP Thu Jul :: UTC x86_64 x86_64 x86_64 GNU/Lin ...
- Sublime Text 3 安装Package Control
原来Subl3安装Package Control很麻烦,现在简单的方法来了 一.简单的安装方法 使用Ctrl+`快捷键或者通过View->Show Console菜单打开命令行,粘贴如下代码: ...
- 内核编译报错Fedora20(友善)
首先说明我的宿主机环境:Fedora20 64位,开发板是友善Smart210(S5PV210——Cotex-A8)!!!马上入题! 按照开发板的用户手册来编译内核,一直报这个错误:/opt/Frie ...
- 基于vw的响应式排版布局
html{ /*iphone6的375px尺寸作为16px基准,600px时字体大小为18px*/ font-size: calc(100% + 2 * (100vw - 375px) / 225); ...