我正在研究ASP .NET MVC 5
网络应用程序并尝试实现搜索功能。我有Renders
个实体,它有大约14个many-to-many
或one-to-one
关系属性。用户使用复选框选择属性,因此我的代码如下:
if (Request.QueryString["attr1"] != "")
{
// linq query that gets all the render according to the request
// to the database that gets converted to t-sql
}
我在代码中有几个if
语句,如上所述我现在修改了我的代码:
var loadedRenders = _db.Renders.Include(r => r.Images)
.Include(m => m.DisplayFormats)
.Include(m => m.DisplayMethods)
.Include(m => m.DominantColors)
.Include(m => m.DrapeTypes)
.Include(m => m.CeilingHeights)
.Include(m => m.RiggingTypes)
.Include(m => m.HardSets)
.Include(m => m.SoftSets)
.Include(m => m.BackDrops)
.Include(m => m.SeatingTypes)
.Include(m => m.StageTypes)
.Include(m => m.VenueType)
.Include(m => m.EventTypes)
.ToList();
if (Request.QueryString["attr1"] != "")
{
// query that filters the renders in loadedRenders using
// linq
}
查询1:
renders = renders.Union(loadedRenders
Where(r => term != null && (r.Title.Contains(term) || r.ClientName.Contains(term) || r.JobId == (term) && r.ActivateRender))).ToList();
查询2:
renders = renders.Union(_db.Renders.Include(r => r.Images)
.Include(m => m.DisplayFormats)
.Include(m => m.DisplayMethods)
.Include(m => m.DominantColors)
.Include(m => m.DrapeTypes)
.Include(m => m.CeilingHeights)
.Include(m => m.RiggingTypes)
.Include(m => m.HardSets)
.Include(m => m.SoftSets)
.Include(m => m.BackDrops)
.Include(m => m.SeatingTypes)
.Include(m => m.StageTypes)
.Include(m => m.VenueType)
.Include(m => m.EventTypes)
.Where(r => term != null && (r.Title.Contains(term) || r.ClientName.Contains(term) || r.JobId == (term) && r.ActivateRender))).ToList();
问题:
两个查询都返回不同的结果,我认为是因为其中一个在T-SQL
执行,而在Linq
执行,我不知道我是否正确但是我是什么我想问的是,有什么方法可以让Query 1
返回与Query 2
相同的结果吗?
答案 0 :(得分:0)
在Query1中,您使用了具有以下条件的loadrenderes
.Where(r => r.ActivateRender == true)
而在query2中,你没有那些可能导致差异的条件
答案 1 :(得分:0)
我说这条线有所不同
.Where(r => r.ActivateRender == true)
它存在于loadedRenders
的赋值中,但不存在于Query2
条件也存在于查询中,但由于operator precedence
,仅适用于最后一个选项如果您将所有a||b||c||...
放在括号中,然后添加&& r.ActivateRender
- 这应该有帮助
答案 2 :(得分:0)
更改查询2中的行
.Where(r => term != null && (r.Title.Contains(term) || r.ClientName.Contains(term) || r.JobId == (term) && r.ActivateRender))).ToList();
到此:
.Where(r => term != null && (r.Title.Contains(term) || r.ClientName.Contains(term) || r.JobId == (term)) && r.ActivateRender)).ToList();
显着的变化是将条件r.ActivateRender
移出OR条件的副作用。
答案 3 :(得分:0)
您可以在内存中应用过滤,而不是使用ToList()调用执行查询。
var loadedRenders = _db.Renders.Include(r => r.Images)
.Include(m => m.DisplayFormats)
...
.Include(m => m.EventTypes)
.AsQueryable(); // AsQueryable does not execute the query to sql as ToList would
if (Request.QueryString["attr1"] != "")
{
// Where() will return IQueryable and the query will not be executed yet
loadedRenders = loadedRenders.Where(<apply filtering here for attr1>);
}
if (Request.QueryString["attr2"] != "")
{
loadedRenders = loadedRenders.Where(<apply filtering here for attr2>);
}
// This will then create sql with all the applied filters
var concreteList = loadedRenders.ToList();