Enable Lazy Loading on AfterSaveEntities using Breeze - entity-framework

I'm using breeze with EF6 and EFContextProvider.
On save changes I'm using :
{ TransactionType = TransactionType.TransactionScope };
I'd like to use lazy loading for validating my entities easier during the AfterSaveEntities delegate but I can't do that. Trying to set LazyLoadingEnabled = false during the transaction doesn't work. Entities still don't load relations when needed.
Is there any way to do that?

No, you'll need to load the entities manually. In fact, as explained in this SO answer, you should create a separate EF context for loading any additional entities.
When the SaveResult is sent back to the client, any additional entities that are attached via navigation properties will be serialized along with the original entities. So you should keep the original context clean unless this is your intent.

Related

Eagerly load all entities in DbContext

Is there a way to configure a DbContext to eagerly load all of its entities? we have attempted:
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
We tried both with and without ProxyCreationEnabled being turned off.
I just happen to know that the DB we are loading in is not very large, doesn't change very often, and is referenced a lot. So keeping it all in memory will be very advantageous.
No, LazyLoadingEnabled disabled does not mean "EagerLoadingEnabled". It is: "not even lazy loading enabled, only loading explicitly requested by you". An EF context will never automatically do eager loading. Just think what could happen with many associations between entities and large databases.
You won't benefit much from pre-loading everything into your context unless you use methods to access the local entities only. You can access local entities by DbSet.Local or DbSet.Find.
Just accessing a DbSet (like context.Customers) will execute a database query anyway. If lazy loading is disabled it may use local entities for navigation properties (called relationship fixup) but otherwise accessing navigation properties will also cause database queries.
It sounds like you should populate an object graph from your database, using a context, and cache it outside the context. Note that if you fetch the data read-only you may want to use the AsNoTracking extension method. (Like context.Customers.AsNoTracking()).
Nope... but if you're looking for the most performant way to load bulk data into EF DbContext, I recommend writing a stored procedure that returns multiple result sets (one for each entity type). EF will automatically hook up the nav properties when the entities are loaded into the context.
Here's instruction on how to do it from both the DB first and code first perspectives:
http://msdn.microsoft.com/en-us/data/jj691402.aspx

Serializing Entity Framework objects for Azure Cache

we use Azure Caching directly (and not through one of the available Entity Framework wrappers). Apparently, for distributed caching, we need to serialize the objects. Unfortunately, this causes issues with lazy-loaded DbContext-based proxies used for navigation properties.
I see we can use a custom serializer in order to map proxies to empty collections (if not loaded) or to normal objects (if loaded), but I am not sure about the implementation. One possible implementation can be based on the one used by WCF, but I am not sure Azure works the same way.
The ideal solution (and that's why I point to ProxyDataContractResolver) would be one where, when serialization happens:
IF the navigation property has been already loaded the data would be serialized as if it were a normal Collection,
and if they are not loaded, they won't be serialized (I would like lazy loading to work back after deserialization for the latter case, but it's acceptable if it doesn't).
Has anyone manually fixed that problem in an elegant way?
Thanks in advance!
I will presume that if you are wanting to cache EF objects, you don't require lazy loading or change tracking on those entities.
I believe that both of those are enabled through object proxies that will cause serialization issues (since you don't want to serialize the proxy).
If you disable the property DbContext.Configuration.ProxyCreationEnabled then serialization of the actual object, not the proxy, should work fine. This is typically required when returning POCO objects over WCF but is likley the same for other serializations scenarios such as this.
If you detach the EF entity from the DbContext before serializing it, that disables lazy loading, so your custom serializer won't try to serialize anything that isn't already part of the entity's graph.
Then when you get it back from the cache, if you attach it to a new (identical) DbContext, that should reenable lazy loading.
(Caveat: once you detach the entity from the context, any new queries that include that same object will create a new, attached, copy, so you will need to code with some care to avoid running into trouble with multiple potentially-different versions of the same object running around. But that said, this should let you do what you want.)

Entity Framework Detach an entity and the related entities gone

When I use Entity Framework, I want to query out a record in a context and add it to another context with the same schema, after query out the record, I detach it from the context, but the related entities are all away, is there any way to solve it?
Thanks in advance!
This is "by design". EF can detach entities only one by one but in the same time EF doesn't support object graphs composed of attached and detached entities. Because of that when you detach entity it will break all relations to the rest of attached object graph. Detaching whole object graph is currently not supported but you can vote for this feature on Data UserVoice.
As a workaround you can turn off lazy loading on your context, use eager loading described by #CodeWarrior to load exactly data you need to pass to other context. Once you have data loaded serialize them to stream and immediately deserialize them to the new instance of the object graph. This is the way how to make deep clone of entity graph which is detached but has all relations intact (turning lazy loading off is needed otherwise serialization will load all other navigation properties as well which can result in much bigger object graph then expected). The only requirement is that your entities must be serializable by serializer of your choice (be aware of circular references which usually require some special handling or additional attributes on your entities).
Are you asking how to load the child entities? If so, you can do eager loading with the .Include method. Given a Person class and a PhoneNumber class where Person has a collection of PhoneNumber, you could do the following:
List<Person> People = db.People.Where(p => p.Name = "Henry")
.Include("PhoneNumbers")
.ToList();
Or you can do what is called explicit loading where you load your entities and call the .Load method on the collections of child and related entities that you want to load. Generally you do this when you do not have LazyLoading enabled (and LazyLoading is enabled by default in 4.0+ don't recall in previous versions).
Regardless of how you query and load them, you will have to detach entities that you want to attach to a different context.
Here is a link to a pretty good MSDN article on loading entities.

Configure Related Entities on modelBuilder instead on Include method

Guys it is possible configure on modelBuilder to set which Entities get related entities instead i use Include method on my LINQ queries?
PROS: I don't need to use Include Method on queries provided by my IRepository Interface, nor reference EntityFramework.dll
No it is not possible. You must either use eager loading, lazy loading or explicitly load each relation:
Eager loading - calling Include. This will load relation during initial query in single database roundtrip.
Lazy loading - making navigation properties virtual. This will load each navigation property when the property is first used by your code. It creates separate database roundtrip for each navigation property.
Explicit loading - you will manually tell property to load (the approach depends on used API - DbContext x ObjectContext). Again this will create separate roundtrip for each navigation property.

Entity Framework Service Layer Update POCO

I am using the Service Layer --> Repository --> Entity Framework (Code-First) w/POCO objects approach, and I am having a hard time with updating entities.
I am using AutoMapper to map my Domain Objects to my View Models and that works good for getting the data, no how do I get that changes back into the database?
Using pure POCO objects, I would assume that there is no sort of change tracking, so I see my only option is to handle it myself. Do you just make sure that your View Models have the EXACT same properties as your Domain Objects? What if I just change a field or two on the View Model? Won't the rest of the fields on the Domain Object get overwritten in the database with default values?
With that said, what is the best approach?
Thanks!
Edit
So what I am stumbling on is this, lets take for example a simple Customer:
1) The Controller has a service, CustomerService, that calls the services GetCustmoerByID method.
2) The Service calls into the CustomerRepository and retrieves the Customer object.
3) Controller uses AutoMapper to map the Customer to the ViewModel.
4) Controller hands the model to the View. Everything is great!
Now in the view you do some modifications of the customer and post it back to the controller to persist the changes to the database.
I would assume at this point the object is detached. So should the model have the EXACT same properties as the Customer object? And do you have to make hidden fields for each item that you do not want to show, so they can persist back?
How do you handle saving the object back to the database? What happens if your view/model only deals with a couple of the fields on the object?
If you're using EF Code First, i.e: the DbContext API, then you still do have change tracking which is taken care of by your context class.
after making changes to your objects, all you have to do is call SaveChanges() on your context and that will persist the changes to your database.
EDIT:
Since you are creating a "copy" of the entity using AutoMapper, then it's no longer attached to your context.
I guess what you could do is something similar to what you would in ASP.NET MVC (with UpdateModel). You can get the original entity from your context, take your ViewModel (which may contain changed properties) and update the old entity, either manually (just modified properties), or using AutoMapper. And then persist the changes using context.SaveChanges().
Another solution would be to send the model entity as [part of] the ViewModel. This way, you'll have your entity attached to the container and change tracking will still work.
Hope this helps :)
You are absolutely right that with a detached object you are responsible for informing the context about changes in your detached entity.
The basic approach is just set the entity as modified. This works for scalar and complex properties but it doesn't work for navigation properties (except FK relations) - for further reading about problems with navigation properties check this answer (it is related to EFv4 and ObjectContext API but same problems are with DbContext API). The disadvantage of this approach is that all fields in DB will be modified. If you just want to modify single field you still have to correctly fill others or your database record will be corrupted.
There is a way to explicitly define which fields have changed. You will set the modified state per property instead of whole entity. It is little bit harder to solve this on generic approach but I tried to show some way for EFv4 and for EFv4.1.
I agree with #AbdouMoumen that it's much simpler to use the model entities at the view level. The service layer should provide an API to persist those entities in the data store (db). The service layer shouldn't dumbly duplicate the repository lawyer (ie: Save(entity) for every entity) but rather provide a high level save for an aggregate of entities. For instance, you could have a Save(order) in the service layer which results in updating more basic entities like inventory, customer, account.