linq or拓展
场景:EF多条件查询时候,遇到多个or的情况
拓展类
#region linq or拓展 public static class Utility { public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> 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<T>(merge(first.Body, secondBody), first.Parameters); } public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) { return first.Compose(second, Expression.And); } public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) { return first.Compose(second, Expression.Or); } } public class ParameterRebinder : ExpressionVisitor { private readonly Dictionary<ParameterExpression, ParameterExpression> map; public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map) { this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>(); } public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> 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<RakutenGoodsReviewList> 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; } Expression<Func<RakutenGoodsReviewList, bool>> 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))
欢迎大家多多交流