改变linq查询以返回所需的结果

时间:2015-04-02 06:59:17

标签: c# asp.net-mvc linq

我正在研究ASP .NET MVC 5网络应用程序并尝试实现搜索功能。我有Renders个实体,它有大约14个many-to-manyone-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相同的结果吗?

4 个答案:

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