当字段不在所选输出中时,您可以将 Where() 添加到 IQueryable 中吗
Can you add a Where() to an IQueryable when the field is not in the selected output
假设我有一个 2 table 加入一个 returns IQueryable 的函数,但输出是一个命名类型,它既不是两个 table 类型:
var qry = from p in Persons
join h in Hobbies on p.PersonId equals h.PersonId
select new OutputType
{
Name = p.FirstName,
Hobby = h.HobbyName
}
return qry
假设现在我想接受这个返回的查询并做类似的事情:
var newQuery = qry.Where( p=>p.Age > 18 )
如您所见,这是一个问题,因为 IQueryable 是 OutputType 类型,所以我无法将一个人的年龄添加到哪里,除非我将年龄添加到 OutputType。
是否有 'breaking into' IQueryable 表达式树并以某种方式添加 lambda 以查询其中指定的源集合并向其添加 Where 子句?或者我是否必须向 OutputType 添加一个 Where 字段,即使我对最终投影它不感兴趣?
以后缩小你的视野比试图原路返回更容易。这是一个精简的示例,说明我如何将方法分层以供重用,以便它们吐出很好的 sql.
private IQueryable<Part> GetParts_Base()
{
//Proprietary. Replace with your own.
var context = ContextManager.GetDbContext();
var query = from c in context.Component
where c.Active
//kind of pointless to select into a new object without a join, but w/e
select new Part()
{
PartNumber = c.ComponentNumber,
Description = c.ComponentDescription,
Cost = c.ComponentCost,
Price = c.ComponentPrice
};
return query;
}
//Exclude cost from this view
public IEnumerable<Part_PublicView> GetParts_PublicView(decimal maxPrice)
{
var query = GetParts_Base();
var results = from p in query
where p.Cost < maxPrice
select new Part_PublicView()
{
PartNumber = p.PartNumber,
Description = p.Description,
Price = p.Price
};
return results;
}
public class Part_PublicView
{
public string PartNumber { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
}
private class Part : Part_PublicView
{
public decimal Cost { get; set; }
}
Linq-to-entity 不会因为 select 过早添加额外的列而惩罚您。如您所见,sql 在约束中包含 Cost 列,但在 select.
中不包含
SELECT
1 AS [C1],
[Extent1].[ComponentNumber] AS [ComponentNumber],
[Extent1].[ComponentDescription] AS [ComponentDescription],
[Extent1].[ComponentPrice] AS [ComponentPrice]
FROM [dbo].[Component] AS [Extent1]
WHERE [Extent1].[ComponentCost] < @p__linq__0
假设我有一个 2 table 加入一个 returns IQueryable 的函数,但输出是一个命名类型,它既不是两个 table 类型:
var qry = from p in Persons
join h in Hobbies on p.PersonId equals h.PersonId
select new OutputType
{
Name = p.FirstName,
Hobby = h.HobbyName
}
return qry
假设现在我想接受这个返回的查询并做类似的事情:
var newQuery = qry.Where( p=>p.Age > 18 )
如您所见,这是一个问题,因为 IQueryable 是 OutputType 类型,所以我无法将一个人的年龄添加到哪里,除非我将年龄添加到 OutputType。
是否有 'breaking into' IQueryable 表达式树并以某种方式添加 lambda 以查询其中指定的源集合并向其添加 Where 子句?或者我是否必须向 OutputType 添加一个 Where 字段,即使我对最终投影它不感兴趣?
以后缩小你的视野比试图原路返回更容易。这是一个精简的示例,说明我如何将方法分层以供重用,以便它们吐出很好的 sql.
private IQueryable<Part> GetParts_Base()
{
//Proprietary. Replace with your own.
var context = ContextManager.GetDbContext();
var query = from c in context.Component
where c.Active
//kind of pointless to select into a new object without a join, but w/e
select new Part()
{
PartNumber = c.ComponentNumber,
Description = c.ComponentDescription,
Cost = c.ComponentCost,
Price = c.ComponentPrice
};
return query;
}
//Exclude cost from this view
public IEnumerable<Part_PublicView> GetParts_PublicView(decimal maxPrice)
{
var query = GetParts_Base();
var results = from p in query
where p.Cost < maxPrice
select new Part_PublicView()
{
PartNumber = p.PartNumber,
Description = p.Description,
Price = p.Price
};
return results;
}
public class Part_PublicView
{
public string PartNumber { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
}
private class Part : Part_PublicView
{
public decimal Cost { get; set; }
}
Linq-to-entity 不会因为 select 过早添加额外的列而惩罚您。如您所见,sql 在约束中包含 Cost 列,但在 select.
中不包含SELECT
1 AS [C1],
[Extent1].[ComponentNumber] AS [ComponentNumber],
[Extent1].[ComponentDescription] AS [ComponentDescription],
[Extent1].[ComponentPrice] AS [ComponentPrice]
FROM [dbo].[Component] AS [Extent1]
WHERE [Extent1].[ComponentCost] < @p__linq__0