EpiServer DynamicDataStore LINQ 语句中的 sql 语法不正确
Incorrect sql syntax in EpiServer DynamicDataStore LINQ statement
我正在编写查询以从 Episerver 中的 DynamicDataStore
检索一些数据。当我 运行 代码时,出现以下错误:
System.Data.SqlClient.SqlException: Incorrect syntax near '>'.
相关查询如下:
BlogContentStore store = new BlogContentStore();
IQueryable<UwlBlogPost> posts = store.Posts.Where(p => Blog == p.BlogId && p.ReadyToPost && p.PostOn <= DateTime.Now);
if (taggedPeople.Count() > 0 || taggedDepartments.Count() > 0 || taggedDepartments.Count() > 0)
{
posts = posts.Where(p => p.PeopleTags.Intersect(taggedPeople).Count() > 0
|| p.DepartmentTags.Intersect(taggedDepartments).Count() > 0
|| p.KeywordTags.Intersect(taggedKeywords).Count() > 0);
}
posts = posts.OrderByDescending(p => p.PostOn).Take(DisplayCount);
一切的语法对我来说都很好,编译也很好。
我设法解决了这个问题。查看 SQL 服务器日志,我能够看到 Intersect
语句没有变成 SQL,所以我决定动态创建查询表达式来绕过它:
if (taggedPeople.Count > 0 || taggedDepartments.Count > 0 || taggedKeywords.Count > 0)
{
ParameterExpression paramExpr = Expression.Parameter(typeof(UwlBlogPost), "p");
Expression peopleTagsExpr = Expression.Property(paramExpr, "PeopleTags");
Expression deptTagsExpr = Expression.Property(paramExpr, "DepartmentTags");
Expression keywordTagsExpr = Expression.Property(paramExpr, "KeywordTags");
Expression filterExpr = null;
if(taggedPeople.Count > 0)
{
filterExpr = FilterLambda<string>(taggedPeople, peopleTagsExpr, paramExpr);
}
if(taggedDepartments.Count > 0)
{
Expression filter = FilterLambda<int>(taggedDepartments, deptTagsExpr, paramExpr);
filterExpr = (filterExpr == null) ? filter : MatchAll ? Expression.And(filterExpr, filter) : Expression.Or(filterExpr, filter);
}
if(taggedKeywords.Count > 0)
{
Expression filter = FilterLambda<int>(taggedKeywords, keywordTagsExpr, paramExpr);
filterExpr = (filterExpr == null) ? filter : MatchAll ? Expression.And(filterExpr, filter) : Expression.Or(filterExpr, filter);
}
posts = posts.Where(Expression.Lambda<Func<UwlBlogPost, bool>>(filterExpr, new[] { paramExpr }));
}
private Expression FilterLambda<T>(List<T> tags, Expression field, ParameterExpression paramExpr)
{
Expression firstTag = Expression.Constant(tags.First());
Expression root = Expression.Call(field, tags.GetType().GetMethod("Contains"), firstTag);
if (tags.Count > 1)
{
foreach (T tag in tags.Skip(1))
{
Expression singleTag = Expression.Constant(tag);
Expression cond = Expression.Call(field, tags.GetType().GetMethod("Contains"), singleTag);
root = MatchAll ? Expression.And(root, cond) : Expression.Or(root, cond);
}
}
return root;
}
我正在编写查询以从 Episerver 中的 DynamicDataStore
检索一些数据。当我 运行 代码时,出现以下错误:
System.Data.SqlClient.SqlException: Incorrect syntax near '>'.
相关查询如下:
BlogContentStore store = new BlogContentStore();
IQueryable<UwlBlogPost> posts = store.Posts.Where(p => Blog == p.BlogId && p.ReadyToPost && p.PostOn <= DateTime.Now);
if (taggedPeople.Count() > 0 || taggedDepartments.Count() > 0 || taggedDepartments.Count() > 0)
{
posts = posts.Where(p => p.PeopleTags.Intersect(taggedPeople).Count() > 0
|| p.DepartmentTags.Intersect(taggedDepartments).Count() > 0
|| p.KeywordTags.Intersect(taggedKeywords).Count() > 0);
}
posts = posts.OrderByDescending(p => p.PostOn).Take(DisplayCount);
一切的语法对我来说都很好,编译也很好。
我设法解决了这个问题。查看 SQL 服务器日志,我能够看到 Intersect
语句没有变成 SQL,所以我决定动态创建查询表达式来绕过它:
if (taggedPeople.Count > 0 || taggedDepartments.Count > 0 || taggedKeywords.Count > 0)
{
ParameterExpression paramExpr = Expression.Parameter(typeof(UwlBlogPost), "p");
Expression peopleTagsExpr = Expression.Property(paramExpr, "PeopleTags");
Expression deptTagsExpr = Expression.Property(paramExpr, "DepartmentTags");
Expression keywordTagsExpr = Expression.Property(paramExpr, "KeywordTags");
Expression filterExpr = null;
if(taggedPeople.Count > 0)
{
filterExpr = FilterLambda<string>(taggedPeople, peopleTagsExpr, paramExpr);
}
if(taggedDepartments.Count > 0)
{
Expression filter = FilterLambda<int>(taggedDepartments, deptTagsExpr, paramExpr);
filterExpr = (filterExpr == null) ? filter : MatchAll ? Expression.And(filterExpr, filter) : Expression.Or(filterExpr, filter);
}
if(taggedKeywords.Count > 0)
{
Expression filter = FilterLambda<int>(taggedKeywords, keywordTagsExpr, paramExpr);
filterExpr = (filterExpr == null) ? filter : MatchAll ? Expression.And(filterExpr, filter) : Expression.Or(filterExpr, filter);
}
posts = posts.Where(Expression.Lambda<Func<UwlBlogPost, bool>>(filterExpr, new[] { paramExpr }));
}
private Expression FilterLambda<T>(List<T> tags, Expression field, ParameterExpression paramExpr)
{
Expression firstTag = Expression.Constant(tags.First());
Expression root = Expression.Call(field, tags.GetType().GetMethod("Contains"), firstTag);
if (tags.Count > 1)
{
foreach (T tag in tags.Skip(1))
{
Expression singleTag = Expression.Constant(tag);
Expression cond = Expression.Call(field, tags.GetType().GetMethod("Contains"), singleTag);
root = MatchAll ? Expression.And(root, cond) : Expression.Or(root, cond);
}
}
return root;
}