当字段不在所选输出中时,您可以将 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