我有一个很好的编译查询。我传递了一个product_id,它返回该产品的产品评论信息。
是否可以将此编译的查询用作子查询的源?例如:
from cat in ctx.cat_table
join prod in ctx.prod_table on cat.category_id equals prod.category_id
select new
{
cat_id = cat.category_id,
prod_id = prod.product_id,
name = prod.product_name,
descript = prod.product_description,
price = prod.price,
reviews = (from mcq in mycompiledquery(ctx, prod.product_id)
select new
{
rating = mcq.review_rating,
review = mcq.review_text
}
}
我早期尝试做这样的事情会引发错误:
LINQ to Entities
不支持LINQ表达式节点类型“Invoke”
我想到的一个替代方法是用SQL视图替换我编译的查询,但我担心会出现负面的性能损失。
非常感谢您提出的任何建议。
答案 0 :(得分:2)
您可以在其他查询中使用已编译的查询,但不能使其依赖于外部查询。实例
// You can do
var someParams = 10;
var dataQuery = from x in ctx.SomeData
join y in myCompiledQuery.Invoke(ctx, someParams)
on x.Id equals y.Id
where x.Name = "ABC"
select new { x, y };
// You can't do - this example will not compile but let's use it for description
var dataQuery = from x in ctx.SomeData
join y in myCompiledQuery.Invoke(ctx, x.SomeParams)
on x.Id equals y.Id
where x.Name = "ABC"
select new { x, y };
不同之处在于第一个示例只执行委托(编译的查询是委托)并返回IQueryable
。第二个示例无法执行委托,因为它依赖于外部查询数据,因此它将其作为必须添加到表达式树并在查询执行期间得到的东西。这会失败,因为EF提供程序无法转换委托调用。
答案 1 :(得分:0)
您可以合并和嵌入查询,但我认为您不能使用已编译的查询。但实际上并不重要,因为EF只会编译组合查询一次然后缓存它(数据库后端应该缓存关联的查询计划)。
因此,您可以使用以下内容:
var reviewQuery = from mcq in reviews
select new
{
prod_id = mcq.prod_id
rating = mcq.review_rating,
review = mcq.review_text
};
from cat in ctx.cat_table
join prod in ctx.prod_table on cat.category_id equals prod.category_id
select new
{
cat_id = cat.category_id,
prod_id = prod.product_id,
name = prod.product_name,
descript = prod.product_description,
price = prod.price,
reviews = from r in reviewQuery where r.prod_id == prod_id select r
}