场景:EF多条件查询时候,遇到多个or的情况
拓展类
#region linq or拓展
public static class Utility
{
public static Expression Compose(this Expression first, Expression second, Func merge)
{
// build parameter map (from parameters of second to parameters of first)
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
// replace parameters in the second lambda expression with parameters from the first
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
// apply composition of lambda expression bodies to parameters from the first expression
return Expression.Lambda(merge(first.Body, secondBody), first.Parameters);
}
public static Expressionbool>> And(this Expressionbool>> first, Expressionbool>> second)
{
return first.Compose(second, Expression.And);
}
public static Expressionbool>> Or(this Expressionbool>> first, Expressionbool>> second)
{
return first.Compose(second, Expression.Or);
}
}
public class ParameterRebinder : ExpressionVisitor
{
private readonly Dictionary map;
public ParameterRebinder(Dictionary map)
{
this.map = map ?? new Dictionary();
}
public static Expression ReplaceParameters(Dictionary map, Expression exp)
{
return new ParameterRebinder(map).Visit(exp);
}
protected override Expression VisitParameter(ParameterExpression p)
{
ParameterExpression replacement;
if (map.TryGetValue(p, out replacement))
{
p = replacement;
}
return base.VisitParameter(p);
}
}
#endregion
用法
IQueryable commentListTemp = reviewHistoryEntities.RakutenGoodsReviewLists.Where(r => r.GoodsReviewID.StartsWith(userShop.ShopID + "_"));
//判断商品名
if (!string.IsNullOrWhiteSpace(this.tbGoodsNameReviewGoods.Text))
{
commentListTemp = commentListTemp.Where(r => r.RakutenGoodsReview.GoodsName.Contains(tbGoodsNameReviewGoods.Text.Trim()));
}
//判断商品id such as:10000000,12312,213,2312
if (!string.IsNullOrWhiteSpace(this.tbGoodsIDReviewGoods.Text))
{
string[] ids = tbGoodsIDReviewGoods.Text.Split(new char[] { (',') }, StringSplitOptions.RemoveEmptyEntries);
if (ids.Length > 500)
{
base.ShowErrorMessage("商品ID: 500個以内に設定してください。", uplRank);
return;
}
Expressionbool>> orQuery = q => false;
for (int i = 0; i < ids.Length; i++)
{
string id = ids[i];
orQuery = orQuery.Or(q => q.GoodsReviewID.IndexOf("_" + id) > -1);
}
commentListTemp = commentListTemp.Where(orQuery);
}
//判断关键字
if (!string.IsNullOrWhiteSpace(tbCommentUserReviewGoods.Text))
{
commentListTemp = commentListTemp.Where(r => r.UserName.Contains(tbCommentUserReviewGoods.Text.Trim()));
}
执行时候生成的sql语句
--数据可能会被截断并且可能无法表示服务器上运行的查询。
USE [ReviewHistory];
GO
--类型和值数据不适用于下列变量。它们的值已设为默认值。
DECLARE @p__linq__0 AS SQL_VARIANT;
DECLARE @p__linq__1 AS SQL_VARIANT;
DECLARE @p__linq__2 AS SQL_VARIANT;
DECLARE @p__linq__3 AS SQL_VARIANT;
DECLARE @p__linq__4 AS SQL_VARIANT;
DECLARE @p__linq__5 AS SQL_VARIANT;
DECLARE @p__linq__6 AS SQL_VARIANT;
DECLARE @p__linq__7 AS SQL_VARIANT;
SET @p__linq__0 = NULL;
SET @p__linq__1 = NULL;
SET @p__linq__2 = NULL;
SET @p__linq__3 = NULL;
SET @p__linq__4 = NULL;
SET @p__linq__5 = NULL;
SET @p__linq__6 = NULL;
SET @p__linq__7 = NULL;
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[GoodsReviewID] AS [GoodsReviewID],
[Extent1].[UserPicture] AS [UserPicture],
[Extent1].[UserName] AS [UserName],
[Extent1].[UserSex] AS [UserSex],
[Extent1].[UserReviewScore] AS [UserReviewScore],
[Extent1].[UserReviewTitle] AS [UserReviewTitle],
[Extent1].[UserReviewContent] AS [UserReviewContent],
[Extent1].[UserReviewTime] AS [UserReviewTime],
[Extent1].[IsAfterBuyReview] AS [IsAfterBuyReview],
[Extent1].[UserUseInfo] AS [UserUseInfo],
[Extent1].[HelpedCount] AS [HelpedCount],
[Extent1].[UserReviewUrl] AS [UserReviewUrl],
[Extent1].[SaveTime] AS [SaveTime],
[Extent1].[ExtraField1] AS [ExtraField1],
[Extent1].[ExtraField2] AS [ExtraField2],
[Extent1].[ExtraField3] AS [ExtraField3],
[Extent1].[ExtraField4] AS [ExtraField4],
[Extent1].[ExtraField5] AS [ExtraField5]
FROM [dbo].[YahooGoodsReviewList] AS [Extent1]
WHERE (( CAST(CHARINDEX(@p__linq__0 + N'_', [Extent1].[GoodsReviewID]) AS int)) = 1) AND ((( CAST(CHARINDEX(N'_' + @p__linq__1, [Extent1].[GoodsReviewID]) AS int)) > 0) OR (( CAST(CHARINDEX(N'_' + @p__linq__2, [Extent1].[GoodsReviewID]) AS int)) > 0) OR (( CAST(CHARINDEX(N'_' + @p__linq__3, [Extent1].[GoodsReviewID]) AS int)) > 0) OR (( CAST(CHARINDEX(N'_' + @p__linq__4, [Extent1].[GoodsReviewID]) AS int)) > 0) OR (( CAST(CHARINDEX(N'_' + @p__linq__5, [Extent1].[GoodsReviewID]) AS int)) > 0) OR (( CAST(CHARINDEX(N'_' + @p__linq__6, [Extent1].[GoodsReviewID]) AS int)) > 0) OR (( CAST(CHARINDEX(N'_' + @p__linq__7, [Extent1].[GoodsReviewID]) AS int)) > 0))