如何在需要计数和项目时避免编写重复查询
How to avoid writing duplicate queries when needing counts and then items
我构建了一个连接大约六个表的 LINQ 查询。问题是,出于分页目的,我想首先计算将返回多少项目。因此,我 运行 遇到的问题是必须编写两次完全相同的查询:一次获取项目计数,另一次构建我的项目集合。
示例:
using (var context = new DbContext())
{
var items = from i in context.Table1
join a in context.TableA on i.SomeProperty equals a.SomeProperty
join b in context.TableB on i.SomeOtherProperty equals b.SomeProperty
join c in context.TableC on i.AnotherProperty equals c.SomeProperty
etc.
etc.
select i;
count = items.Count();
}
return count;
.
.
.
using (var context = new DbContext())
{
var items = from i in context.Table1
join a in context.TableA on i.SomeProperty equals a.SomeProperty
join b in context.TableB on i.SomeOtherProperty equals b.SomeProperty
join c in context.TableC on i.AnotherProperty equals c.SomeProperty
etc.
etc.
select new
{
DynamicProp1 = i.SomeProperty,
DyanmicProp2 = a.SomeProperty,
DyanmicProp3 = b.SomePropery,
etc.
etc.
}
... do some stuff with 'items'...
}
我想不出任何方法来避免这种重复查询。我需要访问所有连接的表才能构建我的集合。如果有任何提示或建议,我将不胜感激。
您可以创建方法来获取上下文和 return 具有所有需要实体的项目的 IQueryable:
class Holder
{
TableAItem A{get;set;}
TableBItem B{get;set;}
...
}
IQueryable<Holder> GetQuery(DbContext context)
{
return from i in context.Table1
join a in context.TableA on i.SomeProperty equals a.SomeProperty
join b in context.TableB on i.SomeOtherProperty equals b.SomeProperty
join c in context.TableC on i.AnotherProperty equals c.SomeProperty
...
select new Holder
{
A = i,
B = b
....
};
}
using (var context = new DbContext())
{
var items = GetQuery(context);
count = items.Count();
}
return count;
using (var context = new DbContext())
{
var items = from r in GetQuery(context)
select new
{
DynamicProp1 = r.a.SomeProperty,
DyanmicProp2 = r.a.SomeProperty,
DyanmicProp3 = r.b.SomePropery,
etc.
etc.
}
... do some stuff with 'items'...
}
请记住,进行查询不会执行查询,这称为延迟执行。那么为什么不进行查询,然后将其作为 IQueryable<>
对象传递。例如,考虑以下代码:
只是 return 字符串最后一个字符的简单方法,但它也会写出它在做什么:
public char GetLastChar(string input)
{
Console.WriteLine("GetLastChar from {0}", input);
return input.Last();
}
现在这段代码使用的方法是:
var listOfStuff = new List<string> { "string1", "string2", "string3" };
Console.WriteLine("Making the query");
var results = from s in listOfStuff
select GetLastChar(s);
Console.WriteLine("Before getting count");
var count = results.Count();
Console.WriteLine("Now enumerating the query");
foreach(var s in results)
{
Console.WriteLine(s);
}
您将看到如下输出:
Making the query
Before getting count
GetLastChar from string1
GetLastChar from string2
GetLastChar from string3
3
Now enumerating the query
GetLastChar from string1
1
GetLastChar from string2
2
GetLastChar from string3
3
我构建了一个连接大约六个表的 LINQ 查询。问题是,出于分页目的,我想首先计算将返回多少项目。因此,我 运行 遇到的问题是必须编写两次完全相同的查询:一次获取项目计数,另一次构建我的项目集合。
示例:
using (var context = new DbContext())
{
var items = from i in context.Table1
join a in context.TableA on i.SomeProperty equals a.SomeProperty
join b in context.TableB on i.SomeOtherProperty equals b.SomeProperty
join c in context.TableC on i.AnotherProperty equals c.SomeProperty
etc.
etc.
select i;
count = items.Count();
}
return count;
.
.
.
using (var context = new DbContext())
{
var items = from i in context.Table1
join a in context.TableA on i.SomeProperty equals a.SomeProperty
join b in context.TableB on i.SomeOtherProperty equals b.SomeProperty
join c in context.TableC on i.AnotherProperty equals c.SomeProperty
etc.
etc.
select new
{
DynamicProp1 = i.SomeProperty,
DyanmicProp2 = a.SomeProperty,
DyanmicProp3 = b.SomePropery,
etc.
etc.
}
... do some stuff with 'items'...
}
我想不出任何方法来避免这种重复查询。我需要访问所有连接的表才能构建我的集合。如果有任何提示或建议,我将不胜感激。
您可以创建方法来获取上下文和 return 具有所有需要实体的项目的 IQueryable:
class Holder
{
TableAItem A{get;set;}
TableBItem B{get;set;}
...
}
IQueryable<Holder> GetQuery(DbContext context)
{
return from i in context.Table1
join a in context.TableA on i.SomeProperty equals a.SomeProperty
join b in context.TableB on i.SomeOtherProperty equals b.SomeProperty
join c in context.TableC on i.AnotherProperty equals c.SomeProperty
...
select new Holder
{
A = i,
B = b
....
};
}
using (var context = new DbContext())
{
var items = GetQuery(context);
count = items.Count();
}
return count;
using (var context = new DbContext())
{
var items = from r in GetQuery(context)
select new
{
DynamicProp1 = r.a.SomeProperty,
DyanmicProp2 = r.a.SomeProperty,
DyanmicProp3 = r.b.SomePropery,
etc.
etc.
}
... do some stuff with 'items'...
}
请记住,进行查询不会执行查询,这称为延迟执行。那么为什么不进行查询,然后将其作为 IQueryable<>
对象传递。例如,考虑以下代码:
只是 return 字符串最后一个字符的简单方法,但它也会写出它在做什么:
public char GetLastChar(string input)
{
Console.WriteLine("GetLastChar from {0}", input);
return input.Last();
}
现在这段代码使用的方法是:
var listOfStuff = new List<string> { "string1", "string2", "string3" };
Console.WriteLine("Making the query");
var results = from s in listOfStuff
select GetLastChar(s);
Console.WriteLine("Before getting count");
var count = results.Count();
Console.WriteLine("Now enumerating the query");
foreach(var s in results)
{
Console.WriteLine(s);
}
您将看到如下输出:
Making the query
Before getting count
GetLastChar from string1
GetLastChar from string2
GetLastChar from string3
3
Now enumerating the query
GetLastChar from string1
1
GetLastChar from string2
2
GetLastChar from string3
3