2013-06-05 102 views
2

我有一个复杂的查询,我在代码中使用了好几次。我用它来获得所有项目或只是一个项目:可扩展的Linq查询

from item in _db.Tests ... select getItem(item) 
from item in _db.Tests ... where item.Id == id select getItem(item) 

我想不重复的公共部分,只叫“的getItem”我是否会使用它。

我试图创建一个这样的功能:

from item in _db.Tests ... 

但是编译器会抱怨,因为我确实不是一个选择。

我还可以创建一个:

private IQueryable<Test> getTests() 
{ 
    return from item in _db.Tests ... select item; 
} 

,然后调用它像这样:

from t in getTests() select getItem(t) 

但是,这可能不会利用优化LINQ是能够的,对吧?

你能帮我吗?

编辑

我意识到我的问题是比较复杂的:点(...)实际上是连接和为getItem功能使用信息,从连接和做一些计算。我想有一个函数来获取所有的项目和一个不同的项目来获得一个特定的项目(我想从程序的其余部分隐藏查询逻辑)。

我想这样做的:

private IQueryable<Tuple<Table1, Table2, Table3, Table4>> queryItems() 
{ 
    return from t1 in _db.Table1s 
      join t2 in _db.Table2s on t1.T2ID equals t2.ID into outerT2 from t2 in outerT2.DefaultIfEmpty() 
      join t3 in _db.Table3s on t1.T3ID equals t3.ID into outerT3 from t3 in outerT3.DefaultIfEmpty() 
      join t4 in _db.Table4s on t1.T4ID equals t4.ID into outerT4 from t4 in outerT4.DefaultIfEmpty() 
      select new Tuple<Table1, Table2, Table3, Table4>(t1, t2, t3, t4); 
} 

public IEnumerable<Item> GetItems() 
{ 
    return from i in queryItems() 
      select getItem(i.Item1, i.Item2, i.Item3, i.Item4); 
} 

public Item GetItem(int id) 
{ 
    return from i in queryItems() 
      where i.Item1.ID equals id 
      select getItem(i.Item1, i.Item2, i.Item3, i.Item4); 
} 

我不希望把中的getItem因为queryItems它做一些计算,并在的GetItem(INT ID)的情况下,将运行它每个元素(对吧?)。

这是做这份工作的好方法吗?有更漂亮的方法吗?更有效的方法?

+0

流利的语法?试试看。 –

+0

@newStackExchangeInstance如果使用方法或查询语法,则无关紧要。两人都有能力做他想做的事。 – Servy

+0

@Servy它会更容易。 –

回答

6

您可以使用相同的查询,并只需添加一个条件,如果需要:

var items = from item in _db.Tests ... select getItem(item); 

// Restrict as necessary 
if (fetchSingle) 
    items = items.Where(item => item.Id == id); 

拆分过滤网(Where)到一个单独的通话将没有缺点,因为它会发送相同的查询由于LINQ的延期执行,实际使用结果为IQueryable<T>的服务器。

+0

请注意,如果他的投影不投射“Id”,他可能无法在调用'GetItem'后应用该位置。 – Servy

+0

@Servy True - 之后可能需要这样做。 –

3

但是,这可能不会使用优化LINQ是能够......对吗?

错误。直到您实际尝试迭代查询时,查询提供程序试图将IQueryable转换为实际的数据库查询并执行它。当你有这样的东西:

var query = db.SomeTable; 

你还没有提取整个表;你已经取得什么也没有。如果你有:

var query2 = query.Where(item => item.SomeProperty == "someValue"); 

然后查询提供程序将应用该过滤器到它发送到数据库的查询。

要理解发生的事情,最简单/最好的方法是查看数据库上下文的Log值。它会在您执行查询时确切指示,以及查询是什么。然后你可以确定你正在执行的是你应该在什么时候的查询。