2

我有一个复杂的查询,我在我的代码中多次使用它。我用它来获取所有项目或仅一项:

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) 的情况下,它会为每个元素运行它(对吗?)。

这是完成工作的好方法吗?有没有更漂亮的方法?更有效的方法?

4

2 回答 2

6

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

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

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

将过滤器 ( ) 拆分为单独的调用不会有任何缺点,因为当您实际使用结果时,由于 LINQ 的延迟执行Where,它会将相同的查询发送到服务器。IQueryable<T>

于 2013-06-05T19:47:27.703 回答
3

但这可能不会利用 LINQ 能够进行的优化......对吗?

不正确。直到您实际尝试迭代查询,查询提供程序才尝试将其IQueryable转换为实际的数据库查询并执行它。当你有类似的东西时:

var query =  db.SomeTable;

你还没有拿到整张桌子;你什么也没拿到。如果你有:

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

然后查询提供者将把过滤器应用到它发送到数据库的查询中。

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

于 2013-06-05T19:49:21.373 回答