Извините, что отвечаю на мой вопрос, но я нашел хорошее решение. Тем не менее, я думаю, что в зависимости от того, что вы пытаетесь сделать, есть разные способы выделить разные выражения LINQ без оценки IQueryable. Поэтому я надеюсь, что люди поделятся альтернативными решениями.
Мое решение состояло в том, чтобы создать «представление» для факторизованного запроса. Я называю это представлением, потому что оно имеет много общего с представлением SQL (с точки зрения клиента LINQ). В отличие от представления SQL, оно не может быть проиндексировано или иметь постоянные столбцы. Поэтому использование этого представления становится узким местом, поэтому было бы целесообразно использовать реальное представление SQL.
static public class MyDataContextExtension
{
// The view exposes OrderSummary objects
public class OrderSummary
{
public OrderID { get; set; }
public string FirstProductListed { get; set; }
}
static public IQueryable<OrderSummary> OrderySummaryView(this MyDataContext db)
{
return (
from O in db.Orders
join OD in db.OrderDetails on O.OrderID equals OD.OrderID into OrderDetails
let AProductBought = OrderDetails.First().Select(OD => OD.Product.ProductName)
let TotalCost = OrderDetails.Aggregate(0
select new OrderSummary()
{
OrderID = OD.OrderID,
FirstProductListed = AProductBought.FirstOrDefault()
};
}
}
С этим я могу выделить дублированную часть запроса, заменив исходный запрос следующим:
var result =
from T in db.Transactions
join OS in db.OrderSummaryView() on T.OrderID equals OS.OrderID
select new
{
TransactionID = T.TransactionID,
OrderID = T.OrderID,
FirstProductBought = OS.FirstProductListed
};
Вы можете представить, что добавляются другие столбцы ... Я думаю, что одна интересная вещь заключается в том, что если вы добавляете дополнительные столбцы, но не используете их при окончательном выборе, LINQ фактически не будет запрашивать эти вещи из базы данных. 1009 *