12

我目前正在使用实体框架在 ASP.NET MVC 4 中编写搜索功能。但是,我遇到了一个障碍,我只能找到“坏”的解决方案。

我的搜索函数返回一个包含 4 个参数的模型:

String Name
String Street
String Code
String Province

List<Query> query = (from t in Model select t).ToList();

现在我想过滤我的搜索输入。但是,用户可以决定填写尽可能多的搜索字段。他可以决定使用名称和街道,或名称、街道和省,或...

我能够找到的唯一真正的解决方案包括进行查询IQueryable并检查字段是否已填充 a if,然后使用 a.Where更新查询。由于这目前会给出 m 5 个查询,我想知道是否有更好的解决方案我在这里缺少。

谢谢你帮助我。

4

4 回答 4

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();

IQueryable当您添加 where 语句以及执行ToList()该 sql时,您将有一个。

更新

回答 Luis Hernández 的评论。这就是它的工作原理。在这种情况下,当您从模型中选择时,集合类型为IQueryable. 这意味着它尚未针对数据库执行。要执行查询,您需要应用一些最终方法。告诉 linq 它实际上会执行数据库调用。这些是例如

ToList()
FirstOrDefault()
SingleOrDefault()
Single()
First()
ToDictionary() 

因此,当我们附加 Where 子句而不使用ToList(). 没有执行查询。

请尝试在LinqPad中查询

于 2012-04-18T06:37:32.533 回答
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

于 2012-04-18T06:54:44.633 回答
0

你可以尝试这样的事情

from cars in tblCars
where (cars.colorID == 1) && (cars.Wieght > 500) && (cars.Active == true)
select cars;
于 2012-04-18T06:53:53.300 回答
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);
            }
        }

编辑:

我已经对其进行了编辑以适用于所有属性。当然,您仍然需要一些东西才能使其工作,但是一旦您了解如何使用它,您就可以将它用作所有代码的实用程序,而不是为每种类型硬编码

于 2012-04-18T07:13:14.247 回答