我目前正在使用Entity Framework在ASP.NET MVC 4中编写搜索功能。但是,我遇到了障碍,我只能找到“坏”解决方案。
我的搜索功能返回一个由4个参数组成的模型:
String Name
String Street
String Code
String Province
List<Query> query = (from t in Model select t).ToList();
现在我想过滤我的搜索输入。但是,用户可以决定填写尽可能多的搜索字段。他可以决定使用姓名和街道,或姓名,街道和省份,或......
我能找到的唯一真正的解决方案是进行查询和IQueryable
并检查某个字段是否已填充if
,然后使用.Where
更新查询。
因为这目前会提供5个查询,我想知道是否有更好的解决方案,我在这里缺少。
感谢您的帮助。
答案 0 :(得分:22)
如果我理解你的话。你可能想要这样的东西:
string Name;
string Street;
string Code;
string Province;
var query=(from t in Model select t);
if(Name!=null)
{
query=query.Where (q =>q.Name==Name);
}
if(Street!=null)
{
query=query.Where (q =>q.Street==Street);
}
if(Code!=null)
{
query=query.Where (q =>q.Code==Code);
}
if(Province!=null)
{
query=query.Where (q =>q.Province==Province);
}
List<Query> ls = query.ToList();
当您添加where语句以及执行sql将执行的IQueryable
时,您将拥有ToList()
。
<强>更新强>
回答路易斯·埃尔南德斯的评论。这就是它的工作原理。在这种情况下,当您从模型中进行选择时,集合类型为IQueryable
。这意味着它尚未针对数据库执行。要执行查询,您需要应用一些最终的metod。告诉linq它实际上会进行数据库调用。这些是例如
ToList()
FirstOrDefault()
SingleOrDefault()
Single()
First()
ToDictionary()
因此,当我们在不使用ToList()
的情况下附加Where子句时。没有执行查询。
请在LinqPad
中尝试查询答案 1 :(得分:2)
使用您在此处找到的实体过滤器类:https://servicelayerhelpers.codeplex.com/SourceControl/changeset/view/32810#537055
首先指定您的过滤器,然后将其应用于您的查询。
例如:
var filter = EntityFilter
.Where(c => c.Name == came)
.Where(c => c.City == city);
var customers = FindCustomers(filter);
Customer[] FindCustomers(IEntityFilter filter)
{
var query = context.Customers;
query = filter.Filter(query);
return query.ToArray();
}
有关详情:https://cuttingedge.it/blogs/steven/pivot/entry.php?id=66
答案 2 :(得分:0)
您可以尝试这样的事情
from cars in tblCars
where (cars.colorID == 1) && (cars.Wieght > 500) && (cars.Active == true)
select cars;
答案 3 :(得分:0)
Arion的解决方案当然非常好,我尝试使用反射减少重复次数,希望它有所帮助。
Type myType = myObject.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
foreach (PropertyInfo prop in props)
{
object propValue = prop.GetValue(myObject, null);
if (propValue != null)
{
query = query.Where(q => prop.GetValue(q, null) == propValue);
}
}
修改强>
我已将其编辑为适用于所有属性。当然,你仍然需要一些东西来实现这一点,但是一旦你理解了如何使用它,你可以将它用作所有代码的实用程序,而不是为每种类型对其进行硬编码