C# 在Linq.Table.Where()中使用可选的OR子句
有没有办法在可选块的下面进行ProjectID检查?我是最近从JavaEE转换过来的.Net,我正在寻找类似于Hibernate标准API的东西。我想简化下面的代码块,只需调用Where()一次。我也不确定使用lambdas执行Where()的性能影响,因为我一周前才开始使用.NetC# 在Linq.Table.Where()中使用可选的OR子句,c#,asp.net,linq-to-sql,lambda,C#,Asp.net,Linq To Sql,Lambda,有没有办法在可选块的下面进行ProjectID检查?我是最近从JavaEE转换过来的.Net,我正在寻找类似于Hibernate标准API的东西。我想简化下面的代码块,只需调用Where()一次。我也不确定使用lambdas执行Where()的性能影响,因为我一周前才开始使用.Net public IQueryable<Project> FindByIdOrDescription(string search) { int projectID;
public IQueryable<Project> FindByIdOrDescription(string search)
{
int projectID;
bool isID = int.TryParse(search, out projectID);
IQueryable<Project> projects;
if (isID)
{
projects = dataContext.Projects.Where(p => p.ProjectDescription.Contains(search) || p.ProjectID == projectID);
}
else
{
projects = dataContext.Projects.Where(p => p.ProjectDescription.Contains(search));
}
return projects;
}
public IQueryable findbyidordordescription(字符串搜索)
{
整数投影;
bool-isID=int.TryParse(搜索,out-projectd);
可供选择的项目;
如果(isID)
{
projects=dataContext.projects.Where(p=>p.ProjectDescription.Contains(search)| | p.projectd==projectd);
}
其他的
{
projects=dataContext.projects.Where(p=>p.ProjectDescription.Contains(search));
}
返回项目;
}
委托/表达式可以“链接”,如下所示(未测试的伪代码):
Expression predicate=p=>p.ProjectDescription.Contains(搜索);
如果(isID)
谓词=p=>谓词(p)| | p.ProjectID==ProjectID;
返回dataContext.Where(谓词);
直到您第一次实际访问iQueryTable的元素时,才会解析和执行查询。因此,无论您在何处添加了多少次(您甚至都没有在这里添加),您都不必担心会多次命中数据库。如果您希望选择性地添加和xyz
,您可以简单地链接where
调用:
var projects = dataContext.Projects.Where(p => p.ProjectDescription.Contains(search));
if (isID)
projects = projects.Where(p => p.ProjectID == projectID);
不幸的是,当您想执行或xyz
时,事情就不是那么容易了。要使其工作,您需要手动构建谓词表达式不好看。一种方法是
Expression<Func<Project, bool>> predicate = p => p.ProjectDescription.Contains(search);
if (isID)
{
ParameterExpression param = expr.Body.Parameters[0];
predicate = Expression.Lambda<Func<Project, bool>>(
Expression.Or(
expr.Body,
Expression.Equal(
Expression.Property(param, "ProjectID"),
Expression.Constant(projectID))),
param);
}
var projects = dataContext.Projects.Where(predicate);
但是,请检查生成的SQL。不幸的是,它甚至无法编译。不能在这样的表达式中调用表达式。在LINQ中有其他方法可以这样做吗?也许没有Lambdas?我提供了一个应该可以工作的示例,但它并不漂亮。是的,这看起来比在Hibernate中创建一个新标准要复杂得多。我猜LINQ不支持这样的东西。没错,它非常冗长。但是,对于您的情况,可能有一条捷径。我已经扩展了描述来提到这一点。
Expression<Func<Project, bool>> predicate = p => p.ProjectDescription.Contains(search);
if (isID)
{
ParameterExpression param = expr.Body.Parameters[0];
predicate = Expression.Lambda<Func<Project, bool>>(
Expression.Or(
expr.Body,
Expression.Equal(
Expression.Property(param, "ProjectID"),
Expression.Constant(projectID))),
param);
}
var projects = dataContext.Projects.Where(predicate);
var projects = dataContext.Projects.Where(
p => p.ProjectDescription.Contains(search)
|| (isID && p.ProjectID == projectID));