title: Nesting EF Core Projection in EF Core Projection
body: <p>Can I have a projection method/property, which I can use in another projection method/property?</p>
  <p>I have Domain Entities <code>Customer</code> and <code>Sale</code>.</p>
  <pre class="lang-c# prettyprint-override"><code>public class Customer : IEntity&lt;long&gt;
  {
      public long Id { get; set; }
      public string Name { get; set; }
  
      public virtual ICollection&lt;Sale&gt; Sales { get; set; }
  }
  
  public class Sale : IEntity&lt;long&gt;
  {
      public long Id { get; set; }
      public decimal UnitPrice { get; set; }
      public int Quantity  { get; set; }
      public decimal TotalPrice  { get; set; }
      public DateTimeOffset Date { get; set; }
  
      public long CustomerId { get; set; }
      public virtual Customer Customer { get; set; }
  
      public long EmployeeId { get; set; }
      public virtual Employee Employee { get; set; }
  
      public long ProductId { get; set; }
      public virtual Product Product { get; set; }
  
  </code></pre>
  <p>I know I can nest a projection as follows:</p>
  <pre><code>public class GetCustomerQuery : IGetCustomerQuery
  {
      private readonly IAppDbContext _context;
  
      public GetCustomerQuery(IAppDbContext context)
      {
          _context = context;
      }
  
      public Task&lt;CustomerModel&gt; ExecuteAsync(long id)
      {
          return _context
              .Customers
              .Where(x =&gt; x.Id == id)
              .Select(GetEmployeeProjection())
              .SingleOrDefaultAsync();
      }
  
      private Expression&lt;Func&lt;Domain.Customers.Customer, CustomerModel&gt;&gt; GetEmployeeProjection()
      {
          return x =&gt; new CustomerModel
          {
              Id = x.Id,
              Name = x.Name,
              Sales = x.Sales.Select(y =&gt; new Sale
              {
                  Employee = y.Employee.Name,
                  Product = y.Product.Name,
                  ProductCount = y.Quantity,
                  TotalPrice = y.TotalPrice
              })
          };
      }
  }
  </code></pre>
  <p>But can I separate the projections in two different method, f.e.:</p>
  <pre class="lang-c# prettyprint-override"><code>private Expression&lt;Func&lt;Domain.Customers.Customer, CustomerModel&gt;&gt; GetEmployeeProjection()
  {
      return x =&gt; new CustomerModel
      {
          Id = x.Id,
          Name = x.Name,
          Sales = x.Sales.Select(GetSaleProjection())
      };
  }
  
  private Expression&lt;Func&lt;Domain.Sales.Sale, Sale&gt;&gt; GetSaleProjection()
  {
      return y =&gt; new Sale
      {
          Employee = y.Employee.Name,
          Product = y.Product.Name,
          ProductCount = y.Quantity,
          TotalPrice = y.TotalPrice
      };
  }
  </code></pre>
  <p>And is it more common to write the projection as a method or as a property?</p>
  <p>EDIT: 2020-12-14
  @joakimriedel, adding <code>.AsQueryable()</code> does kind of work, but I also need to add <code>.ToList()</code>, else a runtime exception was thrown (EF Core 5.0.1), as @Ivan Stoev did mention.</p>
  <pre class="lang-c# prettyprint-override"><code>        public Task&lt;CustomerModel&gt; ExecuteAsync(long id)
          {
              return _context
                  .Customers
                  .Where(x =&gt; x.Id == id)
                  .Select(_projection)
                  .SingleOrDefaultAsync();
          }
  
          private static readonly Expression&lt;Func&lt;Domain.Customers.Customer, CustomerModel&gt;&gt; _projection =
              x =&gt; new CustomerModel
              {
                  Id = x.Id,
                  Name = x.Name,
                  Sales = x.Sales
                      .AsQueryable()
                      .Select(_salesProjection)
                      .ToList()
              };
  
          private static readonly Expression&lt;Func&lt;Domain.Sales.Sale, Sale&gt;&gt; _salesProjection =
               x =&gt; new Sale
               {
                   Employee = x.Employee.Name,
                   Product = x.Product.Name,
                   ProductCount = x.Quantity,
                   TotalPrice = x.TotalPrice
               };
  </code></pre>