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的方法,写出来与大家共同学习.(不知道算不算不务正业) ...
随机推荐
- unsilder中的jq深入学习
//trigger $('#foo').on('click', function() { alert($(this).text()); }); $('#foo').trigger('click'); ...
- RabbitMQ学习系列(二): RabbitMQ安装与配置
上一篇,简单介绍了RabbitMQ的情况还有一些相关的概念,这一篇,会讲讲 RabbitMQ安装与配置. 1.安装 Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装RabbitM ...
- win10连vpn
1.首先卸载网络适配器下所有的WAN Miniport 2.打开命令提示符,输入:netsh interface ipv4 uninstall 卸载TCP/IPv4协议. 3.重启电脑后再次打开“命令 ...
- R语言:ggplot2精细化绘图——以实用商业化图表绘图为例
本文版权归http://www.cnblogs.com/weibaar 本文旨在介绍R语言中ggplot2包的一些精细化操作,主要适用于对R画图有一定了解,需要更精细化作图的人,尤其是那些刚从exce ...
- Springsecurity3.1.3配置多个登陆页面
需求:网站的前台和后台不同的url需要不同的登陆页面,不同的异常捕获方式. spring-security3.1以后的版本支持多个<http>标签,因此本文所采用的方式就是使用两个,实际上 ...
- 【bzoj1606】[Usaco2008 Dec]Hay For Sale 购买干草
题目描述 约翰遭受了重大的损失:蟑螂吃掉了他所有的干草,留下一群饥饿的牛.他乘着容量为C(1≤C≤50000)个单位的马车,去顿因家买一些干草. 顿因有H(1≤H≤5000)包干草,每一包都有它的体 ...
- 【bzoj1700】Problem Solving 解题
题目描述 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地说,他们有P (1 <= P <= 300) 道题目要做. 他们还离开了农场并且象普通人一 ...
- Unix网络单词汇总
Chrome开发者工具 Elements(元素).Network(网络).Sources(源代码:调试JS的地方).Timeline(时间线).Profiles(性能分析).Resources(资源: ...
- nuget的搭建及多源冲突
为什么使用nuget来管理类库引用就不再阐述,好处真的一抓一把.在使用nuget的时候,我们如果总去访问别人的nuget源,受限于网络情况的好坏,速度真的没法保证,更别说访问国外的源了.那好,我们来自 ...
- CAD打印线条太粗、线条颜色设置
不管你是使用打印机,还是将CAD转换为PDF文件,如果出现以下情况,线条太粗,根本看不清楚,怎么解决呢? 或者,不想通过图层复杂.繁琐的设置,想将各种颜色线条的CAD全部打印成黑白,或者指定某一种颜色 ...