I'm developing a migration app and I'm having problems with OutOfMemory due to big relations that source model has.
Better explained with an example:
EntityA has 6 relationships (EntityB, EntityC, EntityD...).
EntityB has 8 relationships ...
EntityB1 has 3 relationships ...
And goes on that way.
Then the problem is that when you try to get all information and do all the process, the app throws and OutOfMemory exception.
I would like to know if I can avoid some relationships, or in case that is not possible avoid all relationships. (programatically)
Thanks in advance
You are searching to disable Lazy loading.
Lazy Loading means that entities will be automatically and transparently loaded when you first access property in query.
With EDMX you can disable it editing his properties (F4 on .edmx file).
With Code first, you can use this line :
dbContext.Configuration.LazyLoadingEnabled = false;
Now that you've disabled it, you'll have to include in your queries the relationships you need using :
dbContext.MyEntity.Include(p=> p.MyRelationProperty)
.Include(p=> p.MyOtherRelationProperty)
[...]
.ToList();
OR
dbContext.MyEntity.Include("MyRelationProperty")
.Include("MyRelationProperty.MySubRelationProperty")
.Include("MyOtherRelationProperty")
[...]
.ToList();
Related
I'm trying to write an UpdateStatus method which will only update the Status field of an entity when I save changes to the database. If any other fields in the entity have changed I don't want to save those changes to the database. That is simple enough for the entity's own fields, using:
using (var context = new DataAccessContext())
{
context.Attach(entity);
context.Entry(entity).Property(e => e.StatusCode).IsModified = true;
context.SaveChanges();
}
However, I've discovered that any related entity reachable via a navigation property of the entity I'm setting the status of will be inserted if that related entity does not have a key value set. So if a new Child entity is added to entity.Children by some calling code, and the Child entity ChildId property is 0, that Child will be inserted into the database.
Is there any easy way in EF Core to avoid inserting related entities?
I've found an old StackOverflow post that shows how to do it in the pre-Core Entity Framework: How do I stop Entity Framework from trying to save/insert child objects? However, that answer involves looping over every related entity. Is there an easier way in EF Core?
The reason I'm looking for an easier way is that my hierarchy of entities is 5 layers deep. And I've found that it's not enough to detach just the immediate children of an entity. You have to use nested loops to detach the grandchildren, the great-grandchildren, etc. If you only detach the immediate children they won't be inserted but EF Core will attempt to insert new grandchildren and will crash and burn because it hasn't inserted their parents. It gets pretty messy.
I could just read a fresh copy of an entity from the database before updating its Status but I'm trying to avoid having to do a read before I write.
What you are asking is quite simple in EF Core. If you don't want EF Core change tracker operation to process the related data, set the EntityEntry.State rather than calling DbContext / DbSet methods like Attach, Add, Update, Remove etc.
This behavior is different from EF6 where methods and setting state are doing one and the same, and is partially mentioned in the Saving Related Data - Adding a graph of new entities
documentation topic:
Tip
Use the EntityEntry.State property to set the state of just a single entity. For example, context.Entry(blog).State = EntityState.Modified.
So in your sample, simply replace
context.Attach(entity);
with
context.Entry(entity).State = EntityState.Unchanged;
Entity Framework Core ignores relationships unless you explicitly
include them in queries.
When attaching an entity to the database that has related data/ child properties, those entities will be included in the query.
So to fix this issue all you need to do is set those child properties to null and then EF Core will ignore the child-objects when you're updating the parent-object.
I am loading a set of entities from DbContext using EF5 but each entity is linked to multiple tables and makes it load related entities everytime. Is there anyway that I can turn that off, and not manually project into a new object like
Entity Framework 4 - Repository Pattern - How to avoid full load of entity with nested relation ?
Executive Summary:
Context.Configuration.LazyLoadingEnabled = false;
See Enter Framework Loading options explained
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.
Is it possible to load an entity excluding some properties? One of this entity's properties is expensive to select. I would like to lazy load this property. Is that possible?
Now that you have read everyone's reply, I will give you the correct answer. EF does not support lazy loading of properties. However it does support a much powerful concept then this. It's called table splitting where you can map a table to two entities. Say a product table in the the database can be mapped to product entity and ProductDetail entity. You can then move the expensive fields to the ProductDetail entity and then create a 1..1 association between prodcut and productdetail entity. You can then lazy load the productdetail association only when you need it.
In my performance chapter of my book, I have a recipe called.
13-9. Moving an Expensive Property to Another Entity
Hope that helps!
Julie Lerman has an article on how to split a table
With a scalar property, the only way to selectively not load a certain property is to project in ESQL or L2E:
var q = from p in Context.People
select new
{
Id = p.Id,
Name = p.Name // note no Biography
};
+1 to Dan; doing this lazily is worse than loading it up-front. If you want to control loading, be explicit.
stimms is correct, but be careful while using lazy loading. You may have performance issues and not realize the property is getting loaded at a specific location in your code. This is because it loads the data when you use the property
I prefer to use explicit loading. This way you know when they get loaded and where. Here's a link that gives an example for the LoadProperty http://sankarsan.wordpress.com/2010/05/09/ado-net-entity-framework-data-loading-part-2/
You can also you Eager Loading by using the Include method. Example here:http://wildermuth.com/2008/12/28/Caution_when_Eager_Loading_in_the_Entity_Framework
Given a query over an EntityFramework DbSet, where the targeted entity contains a BigProperty and a SmallProperty,
When you're trying to only access the SmallProperty without loading the BigProperty in memory :
//this query loads the entire entity returned by FirstOrDefault() in memory
//the execution is deferred during Where; the execution happens at FirstOrDefault
db.BigEntities.Where(filter).FirstOrDefault()?.SmallProperty;
//this query only loads the SmallProperty in memory
//the execution is still deferred during Select; the execution happens at FirstOrDefault
//a subset of properties can be selected from the entity, and only those will be loaded in memory
db.BigEntities.Where(filter).Select(e=>e.SmallProperty).FirstOrDefault();
Therefore you could exploit this behaviour to only query the BigProperty where you actually need it, and use select statements to explicitly filter it out everywhere else.
I tested this with the Memory Usage functionality from the Visual Studio debug Diagnostic Tools.
I am getting an error 3007 when I add my entity model to my solution.
I found these links:
Good explination
Short answer
About this error:
Error 1 Error 3007: Problem in Mapping
Fragments starting at lines 89, 94:
Non-Primary-Key column(s) [Person_ID]
are being mapped in both fragments to
different conceptual side properties -
data inconsistency is possible because
the corresponding conceptual side
properties can be independently
modified.
Their Answer: I agree with their conclusion that by simply deleting the Scalar Property Person_ID and leave the Navigation Property my problem is fixed. However this is not very scalable since I am dynamically building my database and my entity is updated very often. I dont want to have to go through and clean up my entity every time I update it.
My Question: Is there a way to fix the error by correcting the way EF builds the entity? Or is there a way to remove the Scalar Property through code? Perhaps there is even a few options that I am overlooking.
Try to remove foreign property column from Entity set using entity model design it will solve your problem
For example
We have two tables one is customer and other one is order, using entity model design we added association between customers and orders when we do this Ado.net entity framework i will add navigation properties to both below tables.
Like
Customer.Orders - Here order is list
Order.Customer
One - Many relation.
So we need to remove property from with name CustomerId[Foreign key column] from Order entity set.
For reference:
http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/2823634f-9dd1-4547-93b5-17bb8a882ac2/
My experience with EF v1 is similar to yours. When the EDM is generated incorrectly and you can't work around the issue, you have to manually edit the EDM. EF v.Next (Entity Framework v4 I believe) will support "Code Only" Entity Data Models, and the EDM designer is supposed to be much better. One or the other improvement should make our lives easier. Until then...