Skip to content

Commit 3e8fed4

Browse files
2881028810
authored andcommitted
- 增加 LambdaExpression 扩展方法 And/Or/Not 快速拼接表达式;
1 parent 06ff0a4 commit 3e8fed4

File tree

11 files changed

+190
-8
lines changed

11 files changed

+190
-8
lines changed

Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
5-
<Version>0.6.11</Version>
5+
<Version>0.6.12</Version>
66
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
77
<Authors>YeXiangQin</Authors>
88
<Description>FreeSql 扩展包,可实现【延时加载】属性.</Description>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq.Expressions;
4+
using Xunit;
5+
6+
namespace FreeSql.Tests.Extensions {
7+
public class LambadaExpressionExtensionsTest {
8+
9+
[Fact]
10+
public void And() {
11+
Expression<Func<testExpAddOr, bool>> where = a => a.id == Guid.Empty;
12+
13+
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", ""));
14+
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", ""));
15+
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", ""));
16+
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", ""));
17+
}
18+
19+
[Fact]
20+
public void Or() {
21+
Expression<Func<testExpAddOr, bool>> where = a => a.id == Guid.Empty;
22+
23+
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", ""));
24+
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", ""));
25+
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", ""));
26+
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", ""));
27+
}
28+
29+
[Fact]
30+
public void Not() {
31+
Expression<Func<testExpAddOr, bool>> where = a => a.id == Guid.Empty;
32+
33+
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", ""));
34+
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", ""));
35+
}
36+
37+
class testExpAddOr {
38+
public Guid id { get; set; }
39+
40+
public int num { get; set; }
41+
}
42+
}
43+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using FreeSql;
2+
using System;
3+
using System.Collections.Concurrent;
4+
using System.Collections.Generic;
5+
using System.ComponentModel;
6+
using System.Data;
7+
using System.Drawing;
8+
using System.Linq;
9+
using System.Linq.Expressions;
10+
using System.Reflection;
11+
12+
namespace System.Linq.Expressions {
13+
public static partial class LambadaExpressionExtensions {
14+
15+
/// <summary>
16+
/// 使用 and 拼接两个 lambda 表达式
17+
/// </summary>
18+
/// <returns></returns>
19+
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> exp1, Expression<Func<T, bool>> exp2) => And(exp1, true, exp2);
20+
/// <summary>
21+
/// 使用 and 拼接两个 lambda 表达式
22+
/// </summary>
23+
/// <typeparam name="T"></typeparam>
24+
/// <param name="exp1"></param>
25+
/// <param name="condition">true 时生效</param>
26+
/// <param name="exp2"></param>
27+
/// <returns></returns>
28+
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> exp1, bool condition, Expression<Func<T, bool>> exp2) {
29+
if (condition == false) return exp1;
30+
if (exp1 == null) return exp2;
31+
if (exp2 == null) return exp1;
32+
33+
ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
34+
NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);
35+
36+
var left = visitor.Replace(exp1.Body);
37+
var right = visitor.Replace(exp2.Body);
38+
var body = Expression.AndAlso(left, right);
39+
return Expression.Lambda<Func<T, bool>>(body, newParameter);
40+
}
41+
42+
/// <summary>
43+
/// 使用 or 拼接两个 lambda 表达式
44+
/// </summary>
45+
/// <returns></returns>
46+
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> exp1, Expression<Func<T, bool>> exp2) => Or(exp1, true, exp2);
47+
/// <summary>
48+
/// 使用 or 拼接两个 lambda 表达式
49+
/// </summary>
50+
/// <typeparam name="T"></typeparam>
51+
/// <param name="exp1"></param>
52+
/// <param name="condition">true 时生效</param>
53+
/// <param name="exp2"></param>
54+
/// <returns></returns>
55+
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> exp1, bool condition, Expression<Func<T, bool>> exp2) {
56+
if (condition == false) return exp1;
57+
if (exp1 == null) return exp2;
58+
if (exp2 == null) return exp1;
59+
60+
ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
61+
NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);
62+
63+
var left = visitor.Replace(exp1.Body);
64+
var right = visitor.Replace(exp2.Body);
65+
var body = Expression.OrElse(left, right);
66+
return Expression.Lambda<Func<T, bool>>(body, newParameter);
67+
}
68+
69+
/// <summary>
70+
/// 将 lambda 表达式取反
71+
/// </summary>
72+
/// <typeparam name="T"></typeparam>
73+
/// <param name="exp"></param>
74+
/// <param name="condition">true 时生效</param>
75+
/// <returns></returns>
76+
public static Expression<Func<T, bool>> Not<T>(this Expression<Func<T, bool>> exp, bool condition = true) {
77+
if (condition == false) return exp;
78+
if (exp == null) return null;
79+
80+
var candidateExpr = exp.Parameters[0];
81+
var body = Expression.Not(exp.Body);
82+
return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
83+
}
84+
}
85+
86+
internal class NewExpressionVisitor : ExpressionVisitor {
87+
public ParameterExpression _newParameter { get; private set; }
88+
public NewExpressionVisitor(ParameterExpression param) {
89+
this._newParameter = param;
90+
}
91+
public Expression Replace(Expression exp) {
92+
return this.Visit(exp);
93+
}
94+
protected override Expression VisitParameter(ParameterExpression node) {
95+
return this._newParameter;
96+
}
97+
}
98+
}

FreeSql/FreeSql.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
5-
<Version>0.6.11</Version>
5+
<Version>0.6.12</Version>
66
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
77
<Authors>YeXiangQin</Authors>
88
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>

FreeSql/FreeSql.xml

Lines changed: 41 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net452</TargetFrameworks>
5-
<Version>0.6.11</Version>
5+
<Version>0.6.12</Version>
66
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
77
<Authors>YeXiangQin</Authors>
88
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description>

Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
5-
<Version>0.6.11</Version>
5+
<Version>0.6.12</Version>
66
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
77
<Authors>YeXiangQin</Authors>
88
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description>

Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
5-
<Version>0.6.11</Version>
5+
<Version>0.6.12</Version>
66
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
77
<Authors>YeXiangQin</Authors>
88
<Description>FreeSql 数据库实现,基于 Oracle 11</Description>

Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
5-
<Version>0.6.11</Version>
5+
<Version>0.6.12</Version>
66
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
77
<Authors>YeXiangQin</Authors>
88
<Description>FreeSql 数据库实现,基于 PostgreSQL 9.5</Description>

Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net451</TargetFrameworks>
5-
<Version>0.6.11</Version>
5+
<Version>0.6.12</Version>
66
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
77
<Authors>YeXiangQin</Authors>
88
<Description>FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next</Description>

0 commit comments

Comments
 (0)