There is an Entity with many relationships, when i say to EF load a query on a Entity, it loads all properties(OK) with relationships(i don't want)!
This is a big penalty on performance, because i just need some properties not All relationships.
How to say EF that just load entity's property and Don't load relationships (EntityCollection<TEnitity>) ?
I want load relationships's properties by hand!
Are you sure the navigation properties are being eagerly loaded? They shouldn't be by default. Are you using POCO or Code First? If you are, then you need to make sure your navigation properties are marked "virtual". Virtual properties will be lazy loaded.
To check whether navigation properties are lazy loading or eager loading, you'll want to use a tool like SQL Profiler.
JohnnyO is correct; The default value for ObjectContextOptions.LazyLoadingEnabled is false. However, when I create a model from the database, the default value for the model is true. If you are using the generated EF classes, try setting this to false.
Related
I'm using Entity Framework. I've attached a POCO object representing an entity in the DB to my dbcontext using:
var entity = new MyEntity() { ID = 1, AnotherItemID = 10 };
context.Set<T>().Attach(entity);
So far so good. I can access the set and work with the entity I've added. It's added in the Unchanged state. However, it is only a POCO and not a Proxy. Therefore, when I try to access a navigation property, e.g. myEntity.AnotherItem, I just get a null back.
Does anyone know if there is a way to have EF resolve navigation properties for POCO classes attached in this way? Or of a way to cast the POCO to a proxy class?
Thanks
Update
There are two ways to solve this (of course there may be others too!). One is the Explicit Loading option in the answer below. The other way, which allows lazy loading to work, is to use the DBSet Create method rather than the POCO new keyword when creating entities to be attached. More info about that here:
EF4.3 Code-First, MVC, Lazy Loading After Attaching in POST Action
You can use Explicity Loading:
//When you want to load a reference navigation property
context.Entry(entity).Reference(p => p.AnotherItem).Load();
//When you want to load a collection navigation property
context.Entry(post).Collection(p => p.Items).Load();
I have an entity model with a self relation (parent/child). My entity named Article has a property called parent. This parent is in fact the relation, and ParentID which is the field in the relation. In ef 4 i did this:
using (var dbContext= new DataBaseModel())
{
ArticleTable newEntity= new ArticleTable();
newEntity.name="childArt";
newEntity.ParentID = 1;
dbContext.ArticleTable.Add(newEntity);
dbContext.SaveChanges();
//after calling save I can do this
var parentName = newEntity.Parent.Name;
}
With entity framework 6, this doesn't work any more, I have get the entity from the database again in order to get the related parent entity. Is this because of changes to lazyloading? what should i do different.
The difference is that in EF 4 entities were generated with piles of code that took care of change notification and lazy loading. Since then, the DbContext API with POCOs has become the standard.
If you want the same behavior as with the old 'enriched' entities you must make sure that lazy loading can occur by a number of conditions:
The context must allow lazy loading. It does this by default, but you can turn it off.
The navigation properties you want to lazy load must have the virtual modifier, because
EF must create dynamic proxies. These proxies somewhat resemble the old generated entities in that they are able to execute lazy loading, because they override virtual members of the original classes.
The last (and maybe second) point is probably the only thing for you to pay attention to. If you create a new object by new, it's just a POCO object that can't do lazy loading. However, if you'd create a proxy instead, lazy loading would occur. Fortunately, there is an easy way to create a proxy:
ArticleTable newEntity= dbContext.ArticleTables.Create();
DbSet<T>.Create() creates dynamic proxies -
if the underlying context is configured to create proxies and the entity type meets the requirements for creating a proxy.
I doubt this is possible but I will ask it anyway, just in case, is it possible to adapt lazyloading to only load child object who's 'IsDeleted' property is false?
This is just to help with the fact I need to add .where(x => !x.IsDeleted) to most of my methods, which is messy in my opinion.
edit
My entities are created using CodeFirst
Many thanks
It is possible if you use conditional mapping. In such case EF will never load anything with IsDeleted set to true but in the same time IsDeleted column will not be available in your entity at all (because it will be used for mapping). If your application can also set this flag you will need to map stored procedures for entity - you can even map stored procedure for delete operation which will instead set the flag in the database instead of deleting the item.
I'm experiencing something rather odd. I'm tinkering with NHibernate 3.2 mapping by code and have a very simple object model I'm using just to play.
None of my properties in the entire model are marked as virtual because I dont want lazy loading. I'm mapping by code and in each class mapping I'm setting Lazy(false);
However when it comes to mapping collections, if I try and access a collection after the session has ended I get an error "failed to lazily initialize a collection of role...".
I have to explicitly set collectionMapping.Lazy(CollectionLazy.NoLazy); before it will eager load the collection. It was my understanding that lazy loading was not possible unless your properties in your model were defined at virtuals?
Have I fundamentally missed something?
virtual is needed more than just for lazy loading. NHibernate requires them to be virtual because it creates a run-time proxy of the class and injects behavior.
Virtual properties and methods are only needed for lazy associations (many-to-one or one-to-one) because NHibnerate needs to set a proxy entity on the association property.
Collections (one-to-many and many-to-many) don't need any virtual properties because only the collection is lazy, not the entities in the collection. NHibernate will always use its own collection classes, even if you disable lazy loading.
You still need to use IList<T> instead of List<T>, because NH needs its own collection implementation.
Consider:
You won't get very far in a complex model without lazy loading, except your database fits into RAM or you don't mind to cut you OO model into pieces which destroys both maintainability and performance.
You can have entities without virtual members when you use interfaces to create proxies from. However, you should only use these interfaces to reference to entities, because they could always be proxies.
I've been reading Entity Framework and people were crying over why there was not implicit lazy loading or something. Basically I've been searching things about Lazy Loading and now I know what it is : It is a design pattern which allows us to load objects when they are really needed.
But what is the difference between Explicit Lazy Loading and Implicit Lazy Loading.
Thanks in advance...
If you e.g. have an entity "OrderRow" and another entity "Order", there will be a navigational property on the OrderRow that points to the Order it belongs to.
Currently Entity Framework supports only Explicit Lazy Load which means that if you have retreived a number of OrderRows and want to check something on the Order you need to:
// or is an OrderRow
if(!or.Order.IsLoaded)
or.Order.Load()
or.Order.Cancel();
However if you have implicit lazy loading you don't need the IsLoaded check, it will be done automatically, you can do or.Order.Cancel() directly and the Order will be loaded automatically if needed. This is how linq-to-sql works and it saves some typing and some risk for mistakes. On the other hand it makes it less clear exactly when and how database access will be performed. With implicit load it is easy to write inefficient code that makes one DB roundtrip for each line to be fetched from a table.
Explicit means you explicitly wrote your code to lazy load.
Implicit means that the framework (in this case EF) does lazy loading itself, whether you intended to or not.