-
Notifications
You must be signed in to change notification settings - Fork 0
/
LinqExtension.linq
156 lines (138 loc) · 5.4 KB
/
LinqExtension.linq
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<Query Kind="Program">
<Output>DataGrids</Output>
</Query>
//LINQ扩展方法
void Main()
{
#region test And
{
Expression<Func<string, bool>> where1 = s => s.StartsWith("a");
Expression<Func<string, bool>> where2 = s => s.Length > 10;
Func<string, bool> funcAnd = where1.And(where2).Compile();
funcAnd("abcdefghijklmn").Dump("And");
Func<string, bool> funcOr = where1.And(where2).Compile();
funcOr("abc").Dump("Or");
}
#endregion
#region test MaxOrDefault MinOrDefault
{
var str = Enumerable.Range(1, 10).OrderByDescending(p => p);
var ms = str.AsQueryable().OrderByDescending(s => s).FirstOrDefault();
ms.Dump("MaxOrDefault");
var mins=str.AsQueryable().MinOrDefault();
mins.Dump("MinOrDefault");
}
#endregion
}
/// <summary>LINQ扩展方法</summary>
public static class LinqExtension
{
/// <summary>
/// 与连接
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="left">左条件</param>
/// <param name="right">右条件</param>
/// <returns>新表达式</returns>
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
{
return CombineLambdas(left, right, ExpressionType.AndAlso);
}
/// <summary>
/// 或连接
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="left">左条件</param>
/// <param name="right">右条件</param>
/// <returns>新表达式</returns>
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
{
return CombineLambdas(left, right, ExpressionType.Or);
}
private static Expression<Func<T, bool>> CombineLambdas<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right, ExpressionType expressionType)
{
var visitor = new SubstituteParameterVisitor
{
Sub = {
[right.Parameters[0]] = left.Parameters[0]
}
};
Expression body = Expression.MakeBinary(expressionType, left.Body, visitor.Visit(right.Body));
return Expression.Lambda<Func<T, bool>>(body, left.Parameters[0]);
}
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static TResult MaxOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector) => source.Select(selector).OrderByDescending(_ => _).FirstOrDefault()!;
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <param name="defaultValue"></param>
public static TResult MaxOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector, TResult defaultValue) => source.Select(selector).OrderByDescending(_ => _).FirstOrDefault() ?? defaultValue;
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static TSource MaxOrDefault<TSource>(this IQueryable<TSource> source) => source.OrderByDescending(_ => _).FirstOrDefault()!;
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TSource MaxOrDefault<TSource>(this IQueryable<TSource> source, TSource defaultValue) => source.OrderByDescending(_ => _).FirstOrDefault() ?? defaultValue;
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static TResult MinOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector) => source.Select(selector).OrderBy(_ => _).FirstOrDefault()!;
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TResult MinOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector, TResult defaultValue) => source.Select(selector).OrderBy(_ => _).FirstOrDefault() ?? defaultValue;
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static TSource MinOrDefault<TSource>(this IQueryable<TSource> source) => source.OrderBy(_ => _).FirstOrDefault()!;
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TSource MinOrDefault<TSource>(this IQueryable<TSource> source, TSource defaultValue) => source.OrderBy(_ => _).FirstOrDefault() ?? defaultValue;
}
internal class SubstituteParameterVisitor : ExpressionVisitor
{
internal Dictionary<Expression, Expression> Sub = new Dictionary<Expression, Expression>();
protected override Expression VisitParameter(ParameterExpression node)
{
return Sub.TryGetValue(node, out var newValue) ? newValue : node;
}
}