Entity framework 实体框架构建或传递到何处
我想知道我该怎么做? 事实上,我有一个具有搜索条件的对象(一些要搜索的字段,这意味着条件)。我需要根据条件构建查询,但它使用和连接where。 这就是我所拥有的:Entity framework 实体框架构建或传递到何处,entity-framework,lambda,where,func,Entity Framework,Lambda,Where,Func,我想知道我该怎么做? 事实上,我有一个具有搜索条件的对象(一些要搜索的字段,这意味着条件)。我需要根据条件构建查询,但它使用和连接where。 这就是我所拥有的: public class SearchCriteria { public SearchCriteria() { this.Theme = new HashSet<int>(); } public string KeyWord { get; set; } public
public class SearchCriteria
{
public SearchCriteria()
{
this.Theme = new HashSet<int>();
}
public string KeyWord { get; set; }
public bool? ChildrenFirstCycle { get; set; }
public bool? ChildrenSecondCycle { get; set; }
public bool? Primary { get; set; }
public bool? Secondary { get; set; }
public bool? BachelorArts { get; set; }
public bool? BachelorHumanities { get; set; }
public bool? BachelorScience { get; set; }
public bool? University { get; set; }
public bool? MediumLevelCycle { get; set; }
public bool? HighLevelCycle { get; set; }
public int? DistrictID { get; set; }
public int? CountyID { get; set; }
public int? MunicipalID { get; set; }
public ICollection<int> Theme { get; set; }
}
public IEnumerable<School> GetAllEscuelasBySearchCriteria(SearchCriteria searchCriteria)
{
var Query = this._repository.Retrieve();
if (!string.IsNullOrWhiteSpace(searchCriteria.KeyWord))
{
Query = Query.Where(p => p.Name.Contains(searchCriteria.KeyWord) || p.Grade.Contains(searchCriteria.KeyWord) || p.Email.Contains(searchCriteria.KeyWord) || p.Address.Contains(searchCriteria.KeyWord) || p.Code.Contains(searchCriteria.KeyWord));
}
//Rest of condition
if (RestConditions)
{
Query = Query.Where(p=> REST CONDITIONS);
}
//I need to create a list of func expression and add each expression pass the condition and then a foreach and do an OR for all in List of FUNC
if (searchCriteria.InfantilFirstCycle.HasValue && searchCriteria.InfantilFirstCycle.Value != false)
{
Query = Query.Where(p => (p.value1 > 0 || p.value2 > 0 || p.value3 > 0));
}
if (searchCriteria.InfantilSecondCycle.HasValue && searchCriteria.InfantilSecondCycle.Value != false)
{
Query = Query.Where(p => (p.value4 > 0 || p.value5 > 0 || p.value6 > 0));
}
if (searchCriteria.Primary.HasValue && searchCriteria.Primary.Value != false)
{
Query = Query.Where(p => (p.value7 > 0 || p.value8 > 0 || p.value9 > 0 || p.value10 > 0 || p.value11 > 0 || p.value13 > 0 || p.value14 > 0));
}
return Query.Distinct().OrderBy(c=>c.Name).ToList();
}
公共类搜索条件
{
公共搜索标准()
{
this.Theme=newhashset();
}
公共字符串关键字{get;set;}
公共bool?ChildrenFirstCycle{get;set;}
公共bool?ChildrenSecondCycle{get;set;}
公共布尔?主{get;set;}
公共布尔?次{get;set;}
公共布尔?单身汉{get;set;}
公共布尔?单身汉{get;set;}
公共布尔?学士学位{get;set;}
公立学校?大学{get;set;}
public bool?MediumLevelCycle{get;set;}
public bool?HighLevelCycle{get;set;}
公共int?DistrictID{get;set;}
公共int?CountyID{get;set;}
公共int?市政许可证{get;set;}
公共ICollection主题{get;set;}
}
public IEnumerable GetAllesCellasbySearchCriteria(搜索条件搜索条件)
{
var Query=this._repository.Retrieve();
如果(!string.IsNullOrWhiteSpace(searchCriteria.KeyWord))
{
Query=Query.Where(p=>p.Name.Contains(searchCriteria.KeyWord)| p.Grade.Contains(searchCriteria.KeyWord)| p.Email.Contains(searchCriteria.KeyWord)| p.Code.Contains(searchCriteria.KeyWord));
}
//其余情况
if(rest条件)
{
Query=Query.Where(p=>REST条件);
}
//我需要创建一个func表达式列表,并添加每个表达式,然后通过条件和foreach,并在func列表中对所有表达式执行OR
if(searchCriteria.infantialFirstCycle.HasValue&&searchCriteria.infantialFirstCycle.Value!=false)
{
Query=Query.Where(p=>(p.value1>0 | | p.value2>0 | | p.value3>0));
}
if(searchCriteria.infantalSecondCycle.HasValue&&searchCriteria.infantalSecondCycle.Value!=false)
{
Query=Query.Where(p=>(p.value4>0 | | p.value5>0 | | p.value6>0));
}
if(searchCriteria.Primary.HasValue&&searchCriteria.Primary.Value!=false)
{
Query=Query.Where(p=>(p.value7>0 | | p.value8>0 | | p.value9>0 | | p.value10>0 | | p.value11>0 | p.value13>0 | p.value14>0));
}
返回Query.Distinct().OrderBy(c=>c.Name.ToList();
}
查看此nuget软件包在IQueryable上启用搜索扩展
它将允许您执行以下操作:
var query = this._repository.Retrieve();
query = query.Search(searchCriteria.KeyWord, p => p.Name, p => p.Email, p => p.Address, p => p.Code)
.Where(p => searchCriteria.InfantilFirstCycle == true && (p.value1 > 0 || p.value2 > 0 || p.value3 > 0))
.Where(p => searchCriteria.InfantilSecondCycle == true && (p.value4 > 0 || p.value5 > 0 || p.value6 > 0))
.Where(p => searchCriteria.Primary == true && (p.value7 > 0 || p.value8 > 0 || p.value9 > 0 || p.value10 > 0 || p.value11 > 0 || p.value13 > 0 || p.value14 > 0))
return query.Distinct().OrderBy(c=>c.Name).ToList();
这里提供了源代码以及一些示例用法:
对于附加的where子句,您可以调整searchextensions代码以满足您的需要。类似下面的内容将启用以下语法:
var query = this._repository.Retrieve();
query = query.Search(searchCriteria.KeyWord,
p => p.Name,
p => p.Email,
p => p.Address,
p => p.Code)
if(searchCriteria.InfantilFirstCycle == true)
{
query = query.IntGreaterThan(0, p => p.value1, p => p.value2, p => p.value3);
}
if(searchCriteria.InfantilSecondCycle == true)
{
query = query.IntGreaterThan(0, p => p.value4, p => p.value5, p => p.value6);
}
if(searchCriteria.Primary == true)
{
query = query.IntGreaterThan(0, p => p.value7, p => p.value8, p => p.value9, p => p.value10, p => p.value11, p => p.value13, p => p.value14);
}
return query.Distinct().OrderBy(c=>c.Name).ToList();
下面是启用上述功能的代码。(请注意,这是未经测试编写的,可能需要调整)
公共静态类扩展
{
公共静态IQueryable IntGreaterThan(此IQueryable源,int greaterThanValue,参数表达式[]integerProperties)
{
//用于保存合并的“或”表达式的变量
表达式orExpression=null;
//检索第一个参数以使用accross all表达式
var singleParameter=integerProperties[0]。Parameters.Single();
//创建一个常量来表示搜索词
ConstantExpression greaterThanExpression=表达式.常量(greaterThanValue)
//为每个属性生成一个包含表达式
foreach(IntegerProperty中的变量intProperty)
{
//跨每个属性同步单个参数
var swappedParamExpression=SwapExpressionVisitor.Swap(intProperty,intProperty.Parameters.Single(),singleParameter);
//生成表达式以表示x.[propertyX]>greaterThanValue
var expression=BuildGreaterThanExpression(交换参数表达式,greaterThanExpression);
//将contains expresion添加到现有表达式
orExpression=BuildOrExpression(orExpression,expression);
}
var completeExpression=Expression.Lambda(orExpression,singleParameter);
返回source.Where(completeExpression);
}
私有静态二进制表达式BuildGreaterThanExpression(Expression intProperty,ConstantExpression greaterThanExpression)
{
返回表达式.GreaterThan(intProperty.Body,greaterThanExpression);
}
///
///使用OrElse表达式连接到表达式
///
私有静态表达式BuildOrExpression(表达式existingExpression、表达式expressionToAdd)
{
if(existingExpression==null)
{
返回要添加的表达式;
}
//为每个属性生成“或”表达式
返回表达式.OrElse(existingExpression,expressionToAdd);
}
}
内部类SwapExpressionVisitor:ExpressionVisitor
{
私有只读表达式from、to;
私人SwapExpressionVisitor(表达式从,表达式到)
{
这个@from=@from;
这个;
}
公共静态表达式交换(表达式lambda、表达式from、表达式to)
{
返回表达式.Lambda(
交换(lambda.Body、from、to)、lambda.Parameters);
}
专用静态表达式交换(表达式体、表达式从、表达式到)
{
返回新的SwapExpressionVisitor(从、到)。访问(正文);
}
公共重写表达式访问(表达式节点)
{
return node==this.@from?this.to:base.Visit(节点);
}
}
我遇到了这个问题,最终使用了动态linq。我尝试过,但说base{System.Exception}={“linq to Entities中不支持linq表达式节点类型‘Invoke’。}这正是我想要的。A.
public static class Extensions
{
public static IQueryable<T> IntGreaterThan<T>(this IQueryable<T> source, int greaterThanValue, params Expression<Func<T, int>>[] integerProperties)
{
//Variable to hold merged 'OR' expression
Expression orExpression = null;
//Retrieve first parameter to use accross all expressions
var singleParameter = integerProperties[0].Parameters.Single();
//Create a constant to represent the search term
ConstantExpression greaterThanExpression = Expression.Constant(greaterThanValue)
//Build a contains expression for each property
foreach (var intProperty in integerProperties)
{
//Syncronise single parameter accross each property
var swappedParamExpression = SwapExpressionVisitor.Swap(intProperty, intProperty.Parameters.Single(), singleParameter);
//Build expression to represent x.[propertyX] > greaterThanValue
var expression = BuildGreaterThanExpression(swappedParamExpression, greaterThanExpression);
//Add contains expresion to the existing expression
orExpression = BuildOrExpression(orExpression, expression);
}
var completeExpression = Expression.Lambda<Func<T, bool>>(orExpression, singleParameter);
return source.Where(completeExpression);
}
private static BinaryExpression BuildGreaterThanExpression<T>(Expression<Func<T, int>> intProperty, ConstantExpression greaterThanExpression)
{
return Expression.GreaterThan(intProperty.Body, greaterThanExpression);
}
/// <summary>
/// Connect to expressions using the OrElse expression
/// </summary>
private static Expression BuildOrExpression(Expression existingExpression, Expression expressionToAdd)
{
if (existingExpression == null)
{
return expressionToAdd;
}
//Build 'OR' expression for each property
return Expression.OrElse(existingExpression, expressionToAdd);
}
}
internal class SwapExpressionVisitor : ExpressionVisitor
{
private readonly Expression from, to;
private SwapExpressionVisitor(Expression from, Expression to)
{
this.@from = @from;
this.to = to;
}
public static Expression<T> Swap<T>(Expression<T> lambda, Expression from, Expression to)
{
return Expression.Lambda<T>(
Swap(lambda.Body, from, to), lambda.Parameters);
}
private static Expression Swap(Expression body, Expression from, Expression to)
{
return new SwapExpressionVisitor(from, to).Visit(body);
}
public override Expression Visit(Expression node)
{
return node == this.@from ? this.to : base.Visit(node);
}
}