C# 具有实体框架的Linq中的动态Where
我写了一个函数C# 具有实体框架的Linq中的动态Where,c#,linq,entity-framework,C#,Linq,Entity Framework,我写了一个函数 private Func<CategorizedPosts, bool> CompileExpression(IEnumerable<Category> categories) { Expression predicateBody; ParameterExpression pe = Expression.Parameter(typeof(CategorizedPosts), "post");
private Func<CategorizedPosts, bool> CompileExpression(IEnumerable<Category> categories)
{
Expression predicateBody;
ParameterExpression pe = Expression.Parameter(typeof(CategorizedPosts), "post");
Expression left = Expression.Property(pe, typeof(CategorizedPosts).GetProperty("CATEGORY_ID"));
Expression right = Expression.Constant(categories.ElementAt(0).ID);
Expression equal = Expression.Equal(left, right);
predicateBody = equal;
for (int i = 1, j = categories.Count() - 1; i < categories.Count(); ++i )
{
var category = categories.ElementAt(i);
//y => y.CATEGORY_ID == 1 || y.CATEGORY_ID == 2)
left = Expression.Property(pe, typeof(CategorizedPosts).GetProperty("CATEGORY_ID"));
right = Expression.Constant(category.ID);
equal = Expression.Equal(left, right);
predicateBody = Expression.OrElse(predicateBody, equal);
}
var lll = Expression.Lambda<Func<CategorizedPosts, bool>>(predicateBody, pe);
var compiled = lll.Compile();
return compiled;
}
private Func CompileExpression(IEnumerable类别)
{
表达式谓词库;
ParameterExpression pe=Expression.Parameter(typeof(CategorizedPosts),“post”);
Expression left=Expression.Property(pe,typeof(CategorizedPosts).GetProperty(“CATEGORY_ID”);
Expression right=Expression.Constant(categories.ElementAt(0.ID));
表达式equal=表达式.equal(左、右);
谓词体=相等;
对于(int i=1,j=categories.Count()-1;iy.CATEGORY_ID==1 | | y.CATEGORY_ID==2)
左=Expression.Property(pe,typeof(CategorizedPosts).GetProperty(“CATEGORY_ID”);
右=表达式常数(category.ID);
相等=表达式。相等(左、右);
predicateBody=Expression.OrElse(predicateBody,相等);
}
var lll=Expression.Lambda(谓词库,pe);
var compiled=lll.Compile();
编制报表;
}
它可以编译,但当我尝试运行此查询时
var ctx = db.Posts.Where(x => true);
if(predicate != null)
{
ctx = ctx.Where(x => x.CategorizedPosts.Where(**predicate**).Count() > 0);
}
IList<Post> posts = ctx.OrderByDescending(x => x.CREATION_DATE).Skip((page - 1) * perPage).Take(perPage).Select(x => new Post
{
POST_ID = x.ID,
TYPE = new Type { ID = x.TYPE_ID, NAME = x.Types.NAME },
AUTHOR = new Author()
{
ID = x.AUTHOR_ID,
NAME = x.Authors.NAME,
},
CATEGORIES = x.CategorizedPosts.Select(y => new Category() { ID = y.CATEGORY_ID, NAME = y.Categories.NAME }),
CREATION_DATE = x.CREATION_DATE,
}).ToList();
var ctx=db.Posts.Where(x=>true);
if(谓词!=null)
{
ctx=ctx.Where(x=>x.CategorizedPosts.Where(**谓词**).Count()>0);
}
IList posts=ctx.OrderByDescending(x=>x.CREATION\u DATE)。跳过((第1页)*每页)。获取(每页)。选择(x=>new Post
{
POST_ID=x.ID,
TYPE=新类型{ID=x.TYPE\u ID,NAME=x.Types.NAME},
作者=新作者()
{
ID=x.作者的ID,
NAME=x.Authors.NAME,
},
CATEGORIES=x.CategorizedPosts.Select(y=>newcategory(){ID=y.CATEGORIES\u ID,NAME=y.CATEGORIES.NAME}),
创建日期=x.创建日期,
}).ToList();
EF引发有关实体数据提供程序的内部错误1025的异常。如何使用动态where执行此查询?您可以使用ID集合(
int
)的包含,并将其应用于where,例如:
int[] categorieIds = categories.Select(x => x.Id).ToArray();
ctx = ctx.Where(x => x.CategorizedPosts.Any(c => categorieIds .Contains(c.Id));
一些提示
请记住,实体框架在Where
方法中使用Expression
,而不仅仅是Func
您还可以尝试应用提供一些扩展方法的类,如或,和,非,因此,您可以尝试以下方法:
var predicate = PredicateBuilder.False<Product>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or (p => p.Description.Contains (temp));
}
return dataContext.Products.Where(predicate).ToList();
var predicate=PredicateBuilder.False();
foreach(关键字中的字符串关键字)
{
字符串temp=关键字;
谓词=谓词。或(p=>p.Description.Contains(temp));
}
返回dataContext.Products.Where(谓词).ToList();
您最不希望对EF表达式执行的操作是Compile()。两段代码之间的连接不清楚。正如Henk所说,返回Func
将不允许应用它。相反,返回Expression