none
Loading entities with more than one navigation properties RRS feed

  • Question

  • I have an answer, how can I load an entity providing an array or list of navigation properties, instead of a single. For example, I have Invoice (Customer and Lines), Customer (Invoices), InvoiceLine (Invoice, Product) and Product (InvoiceLines, Supplier) entities (navigation properties between brackets). So, I need to load Invoice entity, using the Customer and Lines.Product navigation properties.

    I'm using the Repository pattern.

    This is the way we load an entity with a single relation (1 - n)

            

    public TEntity GetRelatedCollection(TEntity entity, string relation)         {             Context.SetTrackingState(false);             DbContext dbc = Context asDbContext;             if (dbc != null)             {                 var AttachedEntity = this.Set.Attach(entity);                 var RelatedCollection = dbc.Entry(AttachedEntity).Collection(relation);                 RelatedCollection.Load();             }             Context.SetTrackingState(true);             return entity;         }

    The problem is how to load with many (includes??).

     

    Thursday, October 11, 2012 4:07 PM

Answers

  • Hi Sebas.Spina,

    Welcome to the MSDN forum.

    In addition to lazy loading, Entity Framework have Eagerly Loading and Explicitly Loading. Please check this page: http://msdn.microsoft.com/en-us/data/jj574232.aspx

    Actually, if you use the Eagerly Loading as the following way, the related entities will be loaded automatically into memory. We can eagerly load related entities when we query the entities.

    var query = context.Invoices.Where(p => p.Id == 1).Include(p => p.Customer).Include(p => p.Lines.Product).First();

    Then the query result with the related entities are loaded into memory.

    If you use Explicitly Loading, you can load only part of the collection, but you cannot call First() method. Since it will directly return the first element (whose type is Lines) of a sequence, you cannot call Load() method later.

    context.Entry(entity).Collection(relation).Query().Where(p => p.Id == 1).Load();

    Best Regards,


    Alexander Sun [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Alexander Sun Tuesday, October 23, 2012 8:44 AM
    Tuesday, October 16, 2012 7:23 AM

All replies

  • Hi Sebas.Spina,

    Welcome to the MSDN forum.

    I am not sure what means “load with many”. Do you mean you want to load many navigation properties which are included in one entity? If so, you can do this:

    for(Int32 i=0;i<relation.Length;i++){

    context.Entry(AttachedEntity). Collection (relation[i]).Load();

    //context.Entry(AttachedEntity).Reference(relation[i]).Load();

    }//relation is a string array.

    Note that the Reference method should be used when an entity has a navigation property to another single entity. On the other hand, the Collection method should be used when an entity has a navigation property to a collection of other entities.

    Best Regards,


    Alexander Sun [MSFT]
    MSDN Community Support | Feedback to us

    Monday, October 15, 2012 7:16 AM
  • Thanks for your answer Alexander.

    Sorry, I didn't explain right the question (I'm new for Entity Framework also). Our solution is configured to use lazy loading, and I wanted to ask how to load entities with having the base entity and related navigation properties. Like in my sample:

    Customer (with Invoices navigation property)

    Invoice (with Customer and Lines navigation properties)

    InvoiceLine (with Invoice and Product navogation properties)

    Product (with InvoiceLines and Supplier navigation properties)

    Supplier (with Product navigation property).

    The method will receive the entity and an array of navigation properties, like:

    GetRelated (invoice, "Customer", "Lines.Product"); or 

    GetRelated(invoice, p=> p.Customer, p => p.Lines.First().Product);

    Thanks in advance,

    Monday, October 15, 2012 11:56 AM
  • Hi Sebas.Spina,

    Welcome to the MSDN forum.

    In addition to lazy loading, Entity Framework have Eagerly Loading and Explicitly Loading. Please check this page: http://msdn.microsoft.com/en-us/data/jj574232.aspx

    Actually, if you use the Eagerly Loading as the following way, the related entities will be loaded automatically into memory. We can eagerly load related entities when we query the entities.

    var query = context.Invoices.Where(p => p.Id == 1).Include(p => p.Customer).Include(p => p.Lines.Product).First();

    Then the query result with the related entities are loaded into memory.

    If you use Explicitly Loading, you can load only part of the collection, but you cannot call First() method. Since it will directly return the first element (whose type is Lines) of a sequence, you cannot call Load() method later.

    context.Entry(entity).Collection(relation).Query().Where(p => p.Id == 1).Load();

    Best Regards,


    Alexander Sun [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Alexander Sun Tuesday, October 23, 2012 8:44 AM
    Tuesday, October 16, 2012 7:23 AM