mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 18:52:50 +08:00
- 增加 LambdaExpression 扩展方法 And/Or/Not 快速拼接表达式;
This commit is contained in:
parent
06ff0a4da2
commit
3e8fed416d
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.11</Version>
|
||||
<Version>0.6.12</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 扩展包,可实现【延时加载】属性.</Description>
|
||||
|
43
FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs
Normal file
43
FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using Xunit;
|
||||
|
||||
namespace FreeSql.Tests.Extensions {
|
||||
public class LambadaExpressionExtensionsTest {
|
||||
|
||||
[Fact]
|
||||
public void And() {
|
||||
Expression<Func<testExpAddOr, bool>> where = a => a.id == Guid.Empty;
|
||||
|
||||
Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000' AND a.\"num\" > 0)", g.sqlite.Select<testExpAddOr>().Where(where.And(b => b.num > 0)).ToSql().Replace("\r\n", ""));
|
||||
Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select<testExpAddOr>().Where(where.And(false, b => b.num > 0)).ToSql().Replace("\r\n", ""));
|
||||
Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000' AND a.\"num\" = 1 AND a.\"num\" = 2)", g.sqlite.Select<testExpAddOr>().Where(where.And(b => b.num == 1).And(b => b.num == 2)).ToSql().Replace("\r\n", ""));
|
||||
Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select<testExpAddOr>().Where(where.And(false, b => b.num == 1).And(false, c => c.num == 2)).ToSql().Replace("\r\n", ""));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Or() {
|
||||
Expression<Func<testExpAddOr, bool>> where = a => a.id == Guid.Empty;
|
||||
|
||||
Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE ((a.\"id\" = '00000000-0000-0000-0000-000000000000' OR a.\"num\" > 0))", g.sqlite.Select<testExpAddOr>().Where(where.Or(b => b.num > 0)).ToSql().Replace("\r\n", ""));
|
||||
Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select<testExpAddOr>().Where(where.Or(false, b => b.num > 0)).ToSql().Replace("\r\n", ""));
|
||||
Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (((a.\"id\" = '00000000-0000-0000-0000-000000000000' OR a.\"num\" = 1) OR a.\"num\" = 2))", g.sqlite.Select<testExpAddOr>().Where(where.Or(b => b.num == 1).Or(b => b.num == 2)).ToSql().Replace("\r\n", ""));
|
||||
Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select<testExpAddOr>().Where(where.Or(false, b => b.num == 1).Or(false, c => c.num == 2)).ToSql().Replace("\r\n", ""));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Not() {
|
||||
Expression<Func<testExpAddOr, bool>> where = a => a.id == Guid.Empty;
|
||||
|
||||
Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (not(a.\"id\" = '00000000-0000-0000-0000-000000000000'))", g.sqlite.Select<testExpAddOr>().Where(where.Not()).ToSql().Replace("\r\n", ""));
|
||||
Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select<testExpAddOr>().Where(where.Not(false)).ToSql().Replace("\r\n", ""));
|
||||
}
|
||||
|
||||
class testExpAddOr {
|
||||
public Guid id { get; set; }
|
||||
|
||||
public int num { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
98
FreeSql/Extensions/LambadaExpressionExtensions.cs
Normal file
98
FreeSql/Extensions/LambadaExpressionExtensions.cs
Normal file
@ -0,0 +1,98 @@
|
||||
using FreeSql;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace System.Linq.Expressions {
|
||||
public static partial class LambadaExpressionExtensions {
|
||||
|
||||
/// <summary>
|
||||
/// 使用 and 拼接两个 lambda 表达式
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> exp1, Expression<Func<T, bool>> exp2) => And(exp1, true, exp2);
|
||||
/// <summary>
|
||||
/// 使用 and 拼接两个 lambda 表达式
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="exp1"></param>
|
||||
/// <param name="condition">true 时生效</param>
|
||||
/// <param name="exp2"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> exp1, bool condition, Expression<Func<T, bool>> exp2) {
|
||||
if (condition == false) return exp1;
|
||||
if (exp1 == null) return exp2;
|
||||
if (exp2 == null) return exp1;
|
||||
|
||||
ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
|
||||
NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);
|
||||
|
||||
var left = visitor.Replace(exp1.Body);
|
||||
var right = visitor.Replace(exp2.Body);
|
||||
var body = Expression.AndAlso(left, right);
|
||||
return Expression.Lambda<Func<T, bool>>(body, newParameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用 or 拼接两个 lambda 表达式
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> exp1, Expression<Func<T, bool>> exp2) => Or(exp1, true, exp2);
|
||||
/// <summary>
|
||||
/// 使用 or 拼接两个 lambda 表达式
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="exp1"></param>
|
||||
/// <param name="condition">true 时生效</param>
|
||||
/// <param name="exp2"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> exp1, bool condition, Expression<Func<T, bool>> exp2) {
|
||||
if (condition == false) return exp1;
|
||||
if (exp1 == null) return exp2;
|
||||
if (exp2 == null) return exp1;
|
||||
|
||||
ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
|
||||
NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);
|
||||
|
||||
var left = visitor.Replace(exp1.Body);
|
||||
var right = visitor.Replace(exp2.Body);
|
||||
var body = Expression.OrElse(left, right);
|
||||
return Expression.Lambda<Func<T, bool>>(body, newParameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将 lambda 表达式取反
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="exp"></param>
|
||||
/// <param name="condition">true 时生效</param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> Not<T>(this Expression<Func<T, bool>> exp, bool condition = true) {
|
||||
if (condition == false) return exp;
|
||||
if (exp == null) return null;
|
||||
|
||||
var candidateExpr = exp.Parameters[0];
|
||||
var body = Expression.Not(exp.Body);
|
||||
return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
|
||||
}
|
||||
}
|
||||
|
||||
internal class NewExpressionVisitor : ExpressionVisitor {
|
||||
public ParameterExpression _newParameter { get; private set; }
|
||||
public NewExpressionVisitor(ParameterExpression param) {
|
||||
this._newParameter = param;
|
||||
}
|
||||
public Expression Replace(Expression exp) {
|
||||
return this.Visit(exp);
|
||||
}
|
||||
protected override Expression VisitParameter(ParameterExpression node) {
|
||||
return this._newParameter;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.11</Version>
|
||||
<Version>0.6.12</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
|
||||
|
@ -2349,6 +2349,47 @@
|
||||
<param name="that"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.And``1(System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})">
|
||||
<summary>
|
||||
使用 and 拼接两个 lambda 表达式
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.And``1(System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})">
|
||||
<summary>
|
||||
使用 and 拼接两个 lambda 表达式
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="exp1"></param>
|
||||
<param name="condition">true 时生效</param>
|
||||
<param name="exp2"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``1(System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})">
|
||||
<summary>
|
||||
使用 or 拼接两个 lambda 表达式
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``1(System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})">
|
||||
<summary>
|
||||
使用 or 拼接两个 lambda 表达式
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="exp1"></param>
|
||||
<param name="condition">true 时生效</param>
|
||||
<param name="exp2"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Not``1(System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},System.Boolean)">
|
||||
<summary>
|
||||
将 lambda 表达式取反
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="exp"></param>
|
||||
<param name="condition">true 时生效</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeUtil.NewMongodbId">
|
||||
<summary>
|
||||
生成类似Mongodb的ObjectId有序、不重复Guid
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net452</TargetFrameworks>
|
||||
<Version>0.6.11</Version>
|
||||
<Version>0.6.12</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.11</Version>
|
||||
<Version>0.6.12</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.11</Version>
|
||||
<Version>0.6.12</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 Oracle 11</Description>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.11</Version>
|
||||
<Version>0.6.12</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 PostgreSQL 9.5</Description>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net451</TargetFrameworks>
|
||||
<Version>0.6.11</Version>
|
||||
<Version>0.6.12</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next</Description>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
|
||||
<Version>0.6.11</Version>
|
||||
<Version>0.6.12</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 Sqlite 3.0</Description>
|
||||
|
Loading…
x
Reference in New Issue
Block a user