If an entity A has a FK relationship with entity B, and is represented as a navigational property in entity A inside EF4, when are data from entity B loaded? Is it upon creating an instance of A, or only when B is accessed from within A?
It depends on loading method:
Eager loading - the query loading A contains .Include(a => a.B). In such case both A and related Bs are loaded during query execution
Lazy loading - only A is loaded during the first query and if it is still in scope of living context it can trigger lazy loading of B once navigation property accessed first time
Explicit loading - you will manually trigger loading by calling context.LoadProperty(a, "B");
You're going to want to look into Loading Related Objects, perhaps you're more interested in eager loading.
Related
In SDN3.4.0 when an entity is loaded from database, empty child objects (no #Fetch annotation) are populated with only ids present. In SDN4 this doesn't happen and child objects are not populated with ids (for depth 0). Wanted to understand the reason for this change ?
Is there a way to directly populate child objects in SDN4 when entities are queried using complex cypher queries either from session or repository (using #Query).
The default load level is 1 when using the session or repository load methods. This means all objects directly related to the entity are loaded.
You can override this depth.
#Query does not support depth specification at the moment.
I'm working on an enterprise application that leverages the repository pattern on top of EF 4.1 with eager loading to POCO entities. Typically, a call will look like this:
public IEnumerable<SomeEntity> List(DateTime date)
{
using (var context = ContextFactory.CreateContext()) // Returns a DbContext
{
return CreateQuery<SomeEntity>(context)
.Include("PATH1")
.Include("PATH2")
.Where(...)
.AsNoTracking()
.ToList();
}
}
At some point, the business layer translates these entities into DTOs that are then transmitted via WCF to a web application.
As eager loading is rather expensive, I'm trying to keep .Include's to a minimum, so sometimes related properties are (eagerly) loaded and sometimes they're not. However, the business layer has no idea when related properties are present in the entity, so I get an ObjectContextDisposedException, the reason for which is perfectly clear to me and I don't intend to change the basic strategy (i.e. dispose the context right after eager loading the entities).
However, I need to check whether a particular related property is loaded or not, checking if the related object is null doesn't work (ObjectContextDisposedException), nor is there any kind of IsLoaded() method I could use.
Am I stuck with a try/catch block here or are there any other options?
Turn off lazy loading and check for null will work. Your current solution cannot use lazy loading because you dispose context immediately after running the query:
context.Configuration.LazyLoadingEnabled = false;
I'm using Entity Framework 4.1 and I have a one to many relationship.
When I query the lazy loaded ICollection<T> on the one side of the relationship the whole recordset is returned and it doesn't defer the execution like when I'm querying direct from the Repository IQueryable interface.
Is there any way to make this use deferred execution so I can do a query like
Model.Childs.Where(x => !x.Deleted.HasValue).Skip(10).Take(5);
Thanks in advance,
Tom.
That is principle of lazy loading in EF. Your navigation property is defined in your code and any LINQ query defined on that property is LINQ-to-Objects - it is not translated to SQL. Lazy loading always loads whole collection (as well as eager loading). When you query your repository you are querying IQueryable and using LINQ-to-Entities which is translated to SQL.
As workaround use explicit loading:
dbContext.Entry(Model).Collection(m => m.Childs)
.Query()
.Where(c => !c.Deleted.HasValue)
.Skip(10)
.Take(5)
.Load();
When do you dispose an Entities object context objects in entity framework and MVC?
For example if I have a persons table and I select a record in a controller method, dispose it and pass it back to my view, then the record won't be usable in the view.
Should I be disposing it somehow after my view is processed? or not disposing it at all?
One option is to create it in Global.asax's begin request event, and dispose of it in Global.asax's end request event. Every page simply uses that one (stored and obtained in HttpContext.Current.Items or in thread local storage) without disposing it. That lets it be available to your view to do lazy loading but still disposes of it after the request is completed.
The other option is to make sure everything you need is already loaded before calling your view (via .First(), .ToList(), and .Include(property) to include navigation property data) and dispose of it immediately. Both methods work.
I assume you're talking about disposing the Entity Framework "Contexts," since the objects themselves aren't disposable.
We've found it best to leave the entities themselves in our data layer and map them to POCOs/DTOs that contain all the information we need for a given view. That way we're not trying to lazy-load data while we render our view. We wrap the data-access code in a using(var context = contextFactory.Get()), so that the context will automatically be disposed before the method ends, but after we have loaded all the data we're retrieving into an in-memory collection.
Let's consider typical usage pattern of user, you will never just open one item and go away, in fact we move back and forth between items, search and review items again, modify and save them.
If you keep your ObjectContext alive for entire session, you will use little more memory per user, but you will reduce your application to database transfers, and you will be able to accumulate changes. And save changes at once. Since EF implements Identity Pattern, you will not be loading multiple copies of same object.
Otherwise if you dispose ObjectContext, will reduce memory but will increase overhead of loading objects again and again. You might be loading multiple copies of same object again and again over views and increasing query load on database server.
I'm trying to create a POCO proxy for an entity already known to be in the database--similar to the nHibernate Session.Load().
I'd like to set the ID value and then if any other properties are accessed on the entity, the other properties are lazy-loaded--again, similar to the nHibernate Session.Load()
I've tried creating a proxy with ObjectContext.CreateObject(), setting the ID value, and attaching it to the context. But the properties don't lazy-load when accessed. The navigation properties, however, will lazy-load just fine.
I'd like this functionality for cases where I need an entity and know the ID, but don't want to force an extra database hit to load the entity. I also want to ensure that the properties can be loaded in the event that they are needed.
Is this possible with Entity Framework 4?
No it is not possible. The reason is that Entity framework supports only lazy loading of navigation properties. You cannot lazy load scalar or complex properties. You must load the entity from database to get them filled.