C# 动态Linq Build Where子句包含许多参数
我会解释我的问题 因此,首先,我使用谓词Linq动态构建Where子句。 我必须动态构建,因为我不知道会有多少参数。让我举个例子。对于A列可以是一个参数,但是对于B列可以是两个参数,如选择的值“Gas”或“Oil”,但这是一个大问题,我无法正确组合这两个列。 因此,该代码可以工作,但返回0项。但我知道还有很多C# 动态Linq Build Where子句包含许多参数,c#,sql,linq,predicatebuilder,C#,Sql,Linq,Predicatebuilder,我会解释我的问题 因此,首先,我使用谓词Linq动态构建Where子句。 我必须动态构建,因为我不知道会有多少参数。让我举个例子。对于A列可以是一个参数,但是对于B列可以是两个参数,如选择的值“Gas”或“Oil”,但这是一个大问题,我无法正确组合这两个列。 因此,该代码可以工作,但返回0项。但我知道还有很多 public List<CarEntity> GetSearchByKCriteria(int cityId, List<string> fuelType, Lis
public List<CarEntity> GetSearchByKCriteria(int cityId, List<string> fuelType, List<string> gearType, List<string> budget,
List<string> caroser, List<string> enginePower)
{
Expression<Func<Car, bool>> query = null;
Expression<Func<Car, bool>> combine = null;
foreach (var bud in budget)
{
if (budget.Count >= 1)
{
if (bud == "1")
{
if (budget.Count > 1)
{
query = car => car.Budget >= 20000 && car.Budget <= 34999;
}
else
{
query = car => car.Budget >= 20000 && car.Budget <= 34999;
}
}
else if (bud == "2")
{
if (query != null)
{
combine = car => (car.Budget >= 35000 && car.Budget <= 49999);
query = query.Or(combine);
}
else
{
query = car => car.Budget >= 35000 && car.Budget <= 49999;
}
}
}
}
foreach (var caros in caroser)
{
if (caros != "-1" && !string.IsNullOrEmpty(caros))
{
if (query != null)
{
if (query.Expand().ToString().ToLower().Contains("karoser"))
{
combine = car => (car.Karoser == caros);
query = query.And(combine);
}
else
{
combine = car => car.Karoser == caros;
query = query.And(combine);
}
}
else
{
query = car => car.Karoser == caros;
}
}
}
foreach (var fuel in fuelType)
{
if (fuel != "-1" && !string.IsNullOrEmpty(fuel))
{
if (query != null)
{
if (query.Expand().ToString().ToLower().Contains("yakituru"))
{
combine = car => (car.YakitTuru==fuel);
query = query.Or(combine);
}
else
{
combine = car => car.YakitTuru == fuel;
query = query.And(combine);
}
}
else
{
query = car => car.YakitTuru == fuel;
}
}
}
foreach (var gear in gearType)
{
if (gear!="-1"&& !string.IsNullOrEmpty(gear))
{
if (query != null)
{
if (query.Expand().ToString().ToLower().Contains("sanzimantipi"))
{
combine = car => (car.SanzimanTipi == gear);
query = query.Or(combine);
}
else
{
combine = car => car.SanzimanTipi == gear;
query = query.And(combine);
}
}
else
{
query = car => car.SanzimanTipi == gear;
}
}
}
foreach (var engine in enginePower)
{
if (enginePower.Count >= 1)
{
if (engine == "1")
{
if (query != null)
{
if (query.Expand().ToString().ToLower().Contains("silindirhacmi"))
{
combine = car => (car.SilindirHacmi >= 0 && car.SilindirHacmi <= 1600);
query = query.Or(combine);
}
else
{
combine = car => (car.SilindirHacmi >= 0 && car.SilindirHacmi <= 1600);
query = query.And(combine);
}
}
else
{
query = car => car.SilindirHacmi >= 0 && car.SilindirHacmi <= 1600;
}
}
if (engine == "3")
{
if (query != null)
{
if (query.Expand().ToString().ToLower().Contains("silindirhacmi"))
{
combine = car => (car.SilindirHacmi >= 1601 && car.SilindirHacmi <= 1800);
query = query.Or(combine);
}
else
{
combine = car => (car.SilindirHacmi >= 1601 && car.SilindirHacmi <= 1800);
query = query.And(combine);
}
}
else
{
query = car => car.SilindirHacmi >= 1601 && car.SilindirHacmi <= 1800;
}
}
}
using (var context = DataContextFactory.CreateContext())
{
var result = (from fkCar in context.Car.Where(query)
join pkCarBrand in context.CarBrand on fkCar.Marka equals pkCarBrand.ID
where fkCar.IsActive == true
select new
{
entity = fkCar,
joinEntity = pkCarBrand
});
List<CarEntity> theCarList = new List<CarEntity>();
foreach (var item in result)
{
CarEntity theEntity = Mapper.Map(item.entity);
theEntity.CarBrand = Mapper.Map(item.joinEntity);
theCarList.Add(theEntity);
}
return theCarList;
}
}
public List GetSearchByKCriteria(int cityId、List fuelType、List gear type、List budget、,
列表控制器、列表引擎电源)
{
表达式查询=null;
表达式combine=null;
foreach(预算中的var bud)
{
如果(budget.Count>=1)
{
如果(巴德=“1”)
{
如果(budget.Count>1)
{
query=car=>car.Budget>=20000&&car.Budget-car.Budget>=20000&&car.Budget(car.Budget>=35000&&car.Budget-car.Budget>=35000&&car.Budget(car.Karoser==caros);
query=query.And(合并);
}
其他的
{
combine=car=>car.Karoser==caros;
query=query.And(合并);
}
}
其他的
{
query=car=>car.Karoser==caros;
}
}
}
foreach(燃料类型中的var燃料)
{
如果(燃油!=“-1”&&&!string.IsNullOrEmpty(燃油))
{
if(查询!=null)
{
如果(query.Expand().ToString().ToLower().Contains(“yakituru”))
{
联合收割机=car=>(car.YakitTuru==燃料);
query=query.Or(合并);
}
其他的
{
联合收割机=汽车=>car.YakitTuru==燃料;
query=query.And(合并);
}
}
其他的
{
query=car=>car.YakitTuru==fuel;
}
}
}
foreach(齿轮类型中的var齿轮)
{
如果(齿轮!=“-1”&&&!string.IsNullOrEmpty(齿轮))
{
if(查询!=null)
{
if(query.Expand().ToString().ToLower().Contains(“sanzimanti”))
{
联合收割机=car=>(car.sanzimantii==档位);
query=query.Or(合并);
}
其他的
{
联合收割机=car=>car.sanzimantii==档位;
query=query.And(合并);
}
}
其他的
{
query=car=>car.sanzimantii==gear;
}
}
}
foreach(发动机功率中的var发动机)
{
如果(enginePower.Count>=1)
{
如果(发动机==“1”)
{
if(查询!=null)
{
if(query.Expand().ToString().ToLower().Contains(“silinderhacmi”))
{
联合收割机=car=>(car.silinderhacmi>=0&&car.silinderhacmi>=0&&car.silinderhacmi.silinderhacmi>=0&&car.silinderhacmi>=1601&&car.silinderhacmi(car.silinderhacmi>=1601&&car.silinderhacmi car.silinderhacmi>=1601&&car.silinderhacmi不久前,我遇到了一个类似的挑战,我想为一个属性提供一个允许值列表,如果匹配,关联实例将通过过滤器。我提出了以下扩展方法:
static public Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
{
if (null == valueSelector)
{
throw new ArgumentNullException("valueSelector");
}
if (null == values) { throw new ArgumentNullException("values"); }
ParameterExpression p = valueSelector.Parameters.Single();
if (!values.Any())
{
return e => false;
}
var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
静态公共表达式构建包含表达式(表达式值选择器,IEnumerable值)
{
if(null==valueSelector)
{
抛出新ArgumentNullException(“valueSelector”);
}
如果(null==值){抛出新的ArgumentNullException(“值”);}
ParameterExpression p=valueSelector.Parameters.Single();
如果(!values.Any())
{
返回e=>false;
}
var equals=values.Select(value=>(Expression)Expression.Equal(valueSelector.Body,Expression.Constant(value,typeof(TValue)));
变量体=等于.聚合((累计,等于)=>表达式或(累计,等于));
返回表达式.Lambda(body,p);
}
这是基于发布在上的讨论和代码。值得注意的是,LINQ to Entities现在支持.Contains()
在查询表达式中。@StriplingWarrior:很高兴知道。到什么时候?嗯……我想是.NET 4.0。它在
子句中的WHERE有一个整洁的小地方。我以前有一个类似的方法,但现在不再需要它了。@EricJ。谢谢你的回复,但老实说,我没有完全实现我的项目。如果你有eSeCelt时间你能告诉我样本或我的代码吗?@ YigITV:你可能想考虑先把代码提交给CoDeEvIEW.StAccExchange。com,把它简化到人们能理解它的点。如果你不能把问题缩小一点,你就很难得到一个好的答案。没有人想读1。50多行代码是免费的,特别是看起来有一半是相同的。