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
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'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();
Using Entity framework v4, and the POCO entity generator T4 templates.
The problem I have is that the Fixup methods are loading hundreds of entities when I assign an associated entity (see line 4 below).
Dim context = New SomeEntities
Dim list = context.Lists.FirstOrDefault(Function(l) l.ListId = 2)
Dim queryDetail = context.CreateObject(Of QueryDetail)()
queryDetail.CriteriaColumnType = context.CriteriaColumnTypes.FirstOrDefault(Function(cct) cct.CriteriaColumnTypeId = 145)
The CriteriaColumnType entity that is being assigned has a collection of QueryDetail objects, and when the assignment is made, the FixUp method on the CriteriaColumnType entity is lazy loading all of the associated QueryDetails.
How can I create the FK association and attach the CriteriaColumnType entity to my QueryDetail entity without loading all of the CriteriaColumnType's QueryDetail records?
Do you need lazy loading here? You can turn it off:
context.ContextOptions.LazyLoadingEnabled = false
I ran into this problem too. An operation that used to take milliseconds started taking 3-4 seconds to run, all because I added a navigation property pointing to a large table.
I solved the problem by just deleting all the fixup code from the T4 template - our project doesn't need that functionality anyway. I deleted everything from this line:
region.Begin("Association Fixup");
to the next region.End() call. I also deleted all calls to the fixup methods from the property setters, registration of CollectionChanged handlers, and the _settingFK flag.
See this question for more on why the fixup code is there: Why is "Fixup" needed for Persistence Ignorant POCO's in EF 4?. It's trying to make sure that if you change one end of a bidirectional association, the other end is also updated. So, e.g., if you create a new BlogPost and set its User property to a user, the fixup logic will automatically add the post to the user's Posts collection.
marc_s answered the other question by linking to POCO Template Code Generation Options. Removing the fixup code from the T4 template changes the template from #2 (basic POCO with fixup) to #1 (basic POCO without fixup).
I'm a newbie to ADO.Net Entity framework 4. I have a set of pocos which I need to map to a legacy database. The problem is that the db field names are different to the poco property names. eg. db field name = 'cusID' and poco property = 'CustomerID'.
What is the best way to map these?
This is exactly the problem EF mapping is designed to solve.
Your POCO class need to match your 'conceptual model'... Not your 'data model'.
If in EF you build your model from the database you simply need to rename your entity properties. Doing this changes the conceptual model - to match your POCO classes - but leaves the storage model unchanged, and sets up the appropriate mappings.
Entity Framework CTP4 has a new feature called Code First that allows you to map POCO property members to database table column names. This blog article may be what you are looking for,
http://theminimalistdeveloper.com/2010/07/28/how-to-map-pocos-to-existing-databases-in-entity-framework-4-0-code-first-and-asp-net-mvc-2/
Additionally, EF CTP 5 - which will be released in the next few weeks - has a better API to fluently configure your own conventions to map your POCO domain classes to existing database structures.
Hope this helps.
Update Here is the new article that discusses how to achieve this in EF4 CTP5
All references that I find for lazy loading say it's possible but they all mention POCOs and that's it. I am using EF4 with the model-first methodology. In my model diagram I have a Project table and a UserObject table, with a 1 to many relationship between them. However, in code, when I have a valid UserObject and I attempt to get the project performing: Project prj = userobj.Project. Unfortunately, this doesn't work as it claims that UserObject.Project is null.
It seems like I have to explicitly load the Project object via calling UserObject.ProjectReference.Load() prior to calling .Project. Is there any way for this to occur automatically when I access the .Project property?
This should work just fine. Right click on the EDMX, click Properties, check that Lazy loading enabled is set for the EDMX.