如何避免在需要计数和项目时写入重复的查询

时间:2015-06-05 23:55:21

标签: entity-framework linq-to-entities

我构建了一个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'...
}      

我想不出任何方法可以避免这种重复的查询。我需要访问所有已连接的表才能构建我的集合。我将不胜感激任何提示或建议。

2 个答案:

答案 0 :(得分:2)

您可以创建获取上下文的方法,并返回包含所有需要实体的项目的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'...
} 

答案 1 :(得分:1)

请记住,查询并不执行它,这称为延迟执行。那么为什么不进行查询然后将其作为IQueryable<>对象传递。例如,请考虑以下代码:

只是一个从字符串中返回最后一个字符的简单方法,但它也会写出它正在做的事情:

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