我有这样的查询
(from u in DataContext.Users
where u.Division == strUserDiv
&& u.Age > 18
&& u.Height > strHeightinFeet
select new DTO_UserMaster
{
Prop1 = u.Name,
}).ToList();
我想根据是否为运行此查询的方法提供了这些条件,添加了各种条件,如年龄,身高。所有条件都包括用户部门。如果提供了年龄,我想将其添加到查询中。同样,如果提供了高度,我也想添加它。
如果要使用sql查询完成,我会使用字符串构建器将它们附加到主strSQL查询。但是在Linq中,我只能想到使用IF条件,其中我将编写相同的查询三次,每个IF块都有一个附加条件。有更好的方法吗?
谢谢你的时间..
答案 0 :(得分:142)
如果您没有调用ToList()
并且最终映射到DTO类型,则可以随时添加Where
子句,并在结束时构建结果:
var query = from u in DataContext.Users
where u.Division == strUserDiv
&& u.Age > 18
&& u.Height > strHeightinFeet
select u;
if (useAge)
query = query.Where(u => u.Age > age);
if (useHeight)
query = query.Where(u => u.Height > strHeightinFeet);
// Build the results at the end
var results = query.Select(u => new DTO_UserMaster
{
Prop1 = u.Name,
}).ToList();
这仍然只会导致对数据库的单次调用,这与在一次传递中编写查询一样有效。
答案 1 :(得分:14)
一个选项。
bool? age = null
(from u in DataContext.Users
where u.Division == strUserDiv
&& (age == null || (age != null && u.Age > age.Value))
&& u.Height > strHeightinFeet
select new DTO_UserMaster
{
Prop1 = u.Name,
}).ToList();
或者您可以切换到linq的方法语法,并使用if条件将表达式附加到where子句。
答案 2 :(得分:11)
我通常使用方法链接但遇到同样的问题。这是我使用的扩展
public static IQueryable<T> ConditionalWhere<T>(
this IQueryable<T> source,
Func<bool> condition,
Expression<Func<T, bool>> predicate)
{
if (condition())
{
return source.Where(predicate);
}
return source;
}
有助于避免链断裂。同样ConditionalOrderBy
和ConditionalOrderByDescending
也很有帮助。
答案 3 :(得分:3)
这是我做类似事情的代码。这是我的WCF SOAP Web服务API上的一种方法。
public FruitListResponse GetFruits(string color, bool? ripe)
{
try
{
FruitContext db = new FruitContext();
var query = db.Fruits.Select(f => f);
if (color != null)
{
query = query.Where(f => f.Color == color);
}
if (ripe != null)
{
query = query.Where(f => f.Ripe == ripe);
}
return new FruitListResponse
{
Result = query.Select(f => new Fruit { Id = f.FruitId, Name = f.Name }).ToList()
};
}
catch (Exception e)
{
return new FruitListResponse { ErrorMessage = e.Message };
}
}
基本查询是Select(f => f)
,这基本上意味着一切,Where
子句可选地附加到它上面。最终的Select
是可选的。我用来将数据库行对象转换为结果“Fruit”对象。
答案 4 :(得分:3)
我只是在我的where子句中使用它
public IList<ent_para> getList(ent_para para){
db.table1.Where(w=>(para.abc!=""?w.para==para.abc:true==true) && (para.xyz!=""?w.xyz==para.xyz:true==true)).ToList();
}
答案 5 :(得分:2)
根据某些条件添加where条件 ...
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="under-navigation">
<div id="search" class="search">
DIV 1
</div>
<div id="category-dropdown-1" class="category-dropdown-1">
<div class="category-menu">
DIV 2
</div>
</div>
</div>
答案 6 :(得分:0)
假设以下参数,
Int? Age = 18;
只需使用&&
和||
条件运算符,我们就可以拥有另一个版本。
(from u in DataContext.Users
where u.Division == strUserDiv
&& (Age == null || u.Age > Age)
&& (Param1 == null || u.param1 == Param1)
&& u.Height > strHeightinFeet
select new DTO_UserMaster
{
Prop1 = u.Name,
}).ToList();
就像Param1一样,您可以添加任意数量的搜索条件参数。
答案 7 :(得分:0)
我只是偶然发现了这个东西,但以为我会使用lambda版本。
首先,我将创建一个类似这样的类以将参数传递到数据层:
public class SearchParameters() {
public int? Age {get; set;}
public string Division {get;set;}
etc
}
然后,在我的数据层中,如下所示:
public IQueryable<User> SearchUsers(SearchParameters params)
{
var query = Context.Users;
if (params.Age.HasValue)
{
query = query.Where(u => u.Age == params.Age.Value);
}
if (!string.IsNullOrEmpty(params.Division)
{
query = query.Where(u => u.Division == params.Division);
}
etc
return query;
}
具体在哪里实现查询由您决定。应用程序和数据之间可能会有一层,可以将特定于数据库的表示形式转换为与数据库无关的(也许您查询多个数据源)。例如,该层可能会从这些来源获取多种类型的可查询对象,并将它们映射到公共POCO表示形式。
答案 8 :(得分:0)
只需添加到上面接受的答案here中, 如果要在联接上进行动态搜索,请考虑在初始linq查询中返回包含两个表(t1,t2)的新对象,以便您可以单独访问它们以进行条件搜索。
var query = from t1 in _context.Table1
join t2 in _context.Table2 on t1.Table1Id equals t2.Table1IdId
select new { t1, t2 };
if (!string.IsNullOrEmpty(searchProperty1))
{
query = query.Where(collection => collection.t1.TableColumn == searchProperty1);
}
if (!string.IsNullOrEmpty(searchProperty2))
{
query = query.Where(collection => collection.t2.TableColumn == searchProperty2);
}
....etc.
我得到了我在寻找here方面的答案,涉及到联接两个表并查询其中两个表中的特定列