4

Scenario: I'd like to add an entity to the database that would have navigation properties and that entity has navigation properties.. and so on. Basically the tables in the database are connected with each other - all of them.

I use EF4.3 and context/request pattern, so I don't want to enable Lazy loading; it would simply just take too much time to load the entity that I need. So far I have learned there is no other way to do it than to use the include method like this:

 context.Set<TEntity>().include("navproperty1").include("navproperty1.navproperty1.1")... and so on.

This way the maintainability would be bad, plus it's a lot of code but is there any other way if I don't want to manually write all the includes for every entity type?

Chris Barlow
  • 3,274
  • 4
  • 31
  • 52
JahManCan
  • 601
  • 3
  • 8
  • 19
  • 2
    Sidenote: navproperty1.navproperty2 will automatically include navproperty1 too. – JustAnotherUserYouMayKnow May 08 '13 at 11:56
  • Are you sure you want that? You could end up with worse performance and very complex SQL queries than to go with lazy loading. Not to mention ammount of data that such query could end up transfering over wire. But, it could be done as an extension method, using reflection over entity type. – Jurica Smircic May 08 '13 at 12:06
  • are you using code first? – Parv Sharma May 08 '13 at 12:22
  • nav property1 wont load automatically nav property2 so far as I tested, but may be I am missing something out. @Jure: Yeah I know its really bad performance-wise but lazyload is not an option for me, because I dont want the proxies to be enabled and that is required for lazy load right?! The reason I tried to include all nav properties is, "A" entity"has 1 : n relation to "B" entity but "B" entity has n : m relation to "C" entity. And if I wouldnt inlcude "C" to "A" and then try to call context.SaveChanges() then all the data would lost between "B" and "C". Any idea maybe how could I solve it? – JahManCan May 08 '13 at 12:32

2 Answers2

7

There are a lot of questions here. I'll try to address each point.

First, Lazy loading isn't always faster. Specially if you are loading ALL the relations.

Second, always avoid "magic strings". I don't know if the Include method which receives a lambda expression (it's an IQueryable extension) is available for EF 4.3. If it's not, you should implement it yourself like shown here and use:

context.Set<TEntity>().include(t => t.NavProp)

"A" entity" has 1 : n relation to "B" entity but "B" entity has n : m relation to "C" entity. And if I wouldnt inlcude "C" to "A" and then try to call context.SaveChanges() then all the data would lost between "B" and "C"

I don't really know what you meant. But, if you want to select a sub-navigation property which belongs to an item in a list you should use this in EF 5: (not sure if it works in 4.3)

context.Set<TEntity>().Include(t => t.Collection.Select(c => c.SubProp))

Other expressions can be found here

If you clarify on that quote maybe I can help more.

Saulo Vallory
  • 959
  • 9
  • 32
  • The include strings are actually really handy, especially if you are implementing JSON-API – NullVoxPopuli Feb 26 '16 at 15:51
  • 2
    Very useful, thank you. Also, to add to your answer - to use a lambda expression in the `.Include()` method, you need to ensure you're `using System.Data.Entity` as I found out. Another way to avoid magic strings would be to use `nameof(Entity.Property)`, also – Geoff James Jun 08 '16 at 10:47
0

take look at this snippet

var dbQuery =
context.Letters.Where(letter => letter.ID == myId)
   .Include(l => l.Recipients.Select(y => y.PersonTitle))//this will include letter.Recipients.PersonTitle
   .Include(l => l.PersonTitle)
   .Include(l => l.Rank)
   .Include(l => l.JobTitle);
theLetter = dbQuery.FirstOrDefault();// maybe null returned

this line

context.Letters.Include(l => l.Recipients.Select(y => y.PersonTitle))

will get letter(s) with its Recipients and you can access PersonTitle which is exist inside Recipients navigation property

thats means navigation property withen navigation property

Basheer AL-MOMANI
  • 14,473
  • 9
  • 96
  • 92