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的方法,写出来与大家共同学习.(不知道算不算不务正业) ...
随机推荐
- [Android]优化相关
尽量减少布局的层次,最多10层,可以通过LinearLayout向RelativeLayout的转变来减少层的数量 使用ListView的时候,getView方法中的对象尽量重用
- QEMU 中的QOM分析
QOM (QEMU Object Model) 类对象的意义: 1:每个类型在系统中都只有且只有一个类对象 2:当系统中的某个类型的实例对象都被销毁了,那么系统就会销毁该类对象了 3:类对象的作用:负 ...
- JavaScript葵花宝典之闭包
闭包,写过JS脚本的人对这个词一定不陌生,都说闭包是JS中最奇幻的一个知识点, 虽然在工作中,项目里经常都会用到~ 但是是不是你已经真正的对它足够的了解~~ 又或者是你代码中出现的闭包,并不是你刻 ...
- Backbone事件模块及其用法
事件模块Backbone.Events在Backbone中占有十分重要的位置,其他模块Model,Collection,View所有事件模块都依赖它.通过继承Events的方法来实现事件的管理,可以说 ...
- 如何在Android应用中引入外部网页
在某些情况下,我们需要在Android应用中引入外部网页,这里记录一下如何操作(其实很简单^.^). 先介绍一下开发环境: 开发工具:Android Studio 1.5 SDK API版本:17 操 ...
- .net导入excel数据到数据库中
在开发过程中我们经常面临着需要将数据导出或者导入到系统中,例如一些生产管理系统,项目管理系统等等都会有这样的需求: 将excel数据到系统中思路:获取excel中每一行的数据,然后存入集合中,批量添加 ...
- css兼容性大坑
一. \:选择IE6+//区分 IE 8(不实用) .title{ color:yellow\0; color: red\9\0;} \9在 IE 6及其以上都可以识别(但是 IE11不识别 ,IE ...
- web加密的基本概念
1.需求 了解web加密的一些基础概念. 2.基本概念 a.对称加密方式 对称加密方式 加密和解密用同一个密钥 不足之处是,交易双方都使用同样钥匙,安全性得不到保证.此外,每对用户每次使用对称加密算法 ...
- 关于a标签自身的click事件所带来的一些影响
众所周知a标签自身带有点击事件<a href="#"></a>从它本身的特性来讲并没有什么不好的影响,但是如果你在a标签里又加入onclick事件则< ...
- centos6安装php5.4以上版本
1.检查当前安装的PHP包 yum list installed | grep php 如果有安装的PHP包,先删除他们 yum remove php.x86_64 php-cli.x86_64 p ...