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的方法,写出来与大家共同学习.(不知道算不算不务正业) ...
随机推荐
- 记一次WinForm程序中主进程打开子进程并传递参数的操作过程(进程间传递参数)
目标:想在WinForm程序之间传递参数.以便子进程作出相应的处理. 一种错误的方法 父进程的主程序: ProcessStartInfo psi = new ProcessStartInfo(); p ...
- ubuntu竖屏显示
xrandr -o left 向左旋转90度 xrandr -o right 向右旋转90度 xrandr -o inverted 上下翻转 xrandr -o normal 回到正常角
- jquery复选框checkbox实现删除
实现这样一个基本需求,页面有很多数据,可以删除一条或多条,删除前判断是否选中至少一条,否则提示. function deleteUser() { //当时是想把内容以str+="" ...
- ASP.NET MVC和EF集成AngularJS开发
参考资料: 如何在ASP.NET MVC和EF中使用AngularJS AngularJS+ASP.NET MVC+SignalR实现消息推送 [AngularJs + ASP.NET MVC]使用A ...
- CSS 高级布局技巧
随着 IE8 逐渐退出舞台,很多高级的 CSS 特性都已被浏览器原生支持,再不学下就要过时了. 用 :empty 区分空元素 兼容性:不支持 IE8 /*假如我们有以上列表:*/ <div cl ...
- ls目录内容
ls:列出目录内容 1.常用参数: -a, –all 列出目录下的所有文件,包括以 . 开头的隐含文件(常用) -A 同-a,但不列出“.”(表示当前目录)和“..”(表示当前目录的父目录). -c ...
- HDU 2296 Ring -----------AC自动机,其实我想说的是怎么快速打印字典序最小的路径
大冥神的代码,以后能贴的机会估计就更少了....所以本着有就贴的好习惯,= =....直接贴 #include <bits/stdc++.h> using LL = long long ; ...
- C++中有关数组的相关问题
1.数组长度相关: strlen(from <string.h>)只是针对字符数组才有的,他不包含\0的长度.无法对其他类型求长度.sizeof()则可以对\0发起作用.记住(a.leng ...
- java 单例模式
懒汉式 public class Singleton{ //@单例类只能有一个实例 //@单例类必须自行创建这个实例 //@单例类必须给所有对象提供这一个实例//必须向整个系统提供这个这个实例 pri ...
- 【Network】TCPDUMP 详解
参考资料: https://www.baidu.com/s?ie=UTF-8&wd=tcpdump%20%E6%8C%87%E5%AE%9Aip tcpdump非常实用的抓包实例: http ...