How to only load certain fields of a child object in Entity Framework 6.1?

c# entity-framework entity-framework-6 linq-to-entities

Question

I'm developing a model with two classes,Product and Transaction .

public class Product
{
    [DataMember]
    public Guid ProductId {get; set;}

    [DataMember]
    public virtual ICollection<Transaction> Transactions { get; set; }
}

public class Transaction
{
    [DataMember]
    public Guid TransactionId {get; set;}

    [DataMember]
    public DateTimeOffset Date { get; set; }

    [DataMember]
    public String Customer { get; set; }
}

How can I conduct a search that returns a product along with the date of its transactions? I made an effort to

var product = db.Products.Include(p => p.Transactions.Select(t => new { t.Date })).Where(p => p.ProductId = productId);

However, it makes an exception:

The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties

Clarification needed: I genuinely want to achieve not loading.TransactionId and Customer when Transaction is stocked.

1
6
4/21/2016 4:18:33 PM

Accepted Answer

You are forced to project your query to an anonymous type or a DTO in order to fulfill your goals. As you can see, the Include extension method allows you to specify the related entities you want to load, which is then translated into a table inner join (or multiple joins; see the Remarks section in the quoted link); however, this does not guarantee that all of the related entities' properties will be loaded. When you dial theSelect If you use one of the two methods I mentioned above, you can pick and choose which columns you wish to project, but you cannot project a Linq to Entities query using an entity type. Therefore, my recommendation is to develop a set of classes (DTOs) in your business logic layer to project the outcomes of your queries, such as:

 public class ProductDTO
 {
    [DataMember]
    public Guid ProductId {get; set;}
    [DataMember]
    public virtual IEnumerable<DateTime> TransactionDates { get; set; }
 }

Later, you could carry out the following:

var product = db.Products.Where(p => p.ProductId = productId)
                         .Select(pr=> new ProductDTO
                         {
                           ProductId = pr.ProductId,
                           TransactionDates = pr.Transactions.Select(tr=>tr.Date),
                         }.ToList();

Evidently, I won't need to call.Include extension technique in this instance, as theSelect A column is being projected fromTransactions table. As you define a Linq query that will later be converted to SQL, the data is not yet loaded at that moment. When does that occur? whenever you callToList extension strategy.

As a final suggestion, I advise you to look into Automapper. After mapping your entities to their corresponding DTOs, your queries might look like this:

var product = db.Products.Where(p => p.ProductId == productId)
                         .ProjectTo<ProductDTO>()    
                         .ToList();

Information aboutProjectTo This link's extension method

6
4/21/2016 6:20:24 PM

Popular Answer

ZZZ_tmp


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow