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.
Related
I have to create and remove attributes based on an api response in Objective C.
For example, Now my api response contains fields "facebook", "whatsapp" and "viber". But in future the reponse can add "youtube". Based on this response, I have to remove all the attributes and values of an entity "Social", and create Four attributes now and set values.
How to do that programmatically? Because the default *.xcdatamodeld file cant help me here, right?
Note: My project is in objective C.
The data model is mutable when the app starts-- you can completely build the model in code, and not use the model editor, for example. But as soon as you load a persistent store file, you must treat the model as fixed. Any changes after loading a persistent store will cause crashes. That means any changes would have to happen before calling either loadPersistentStores(completionHandler:) or addPersistentStore(with:completionHandler:).
Alexander's suggestion of optional attributes is a good one. If you need the model to be more dynamic, you would need to create a new related entity which would store the service name plus whatever information you need to save about the service. If you did this, your Social entity would have a to-many relationship to a new entity called something like Service. Service would have a string property called name that would have values like twitter, facebook, youtube, etc. It would also have whatever other attributes you need to save about the service.
You can create all 4 fields in advance and just make them optional and fill them depending on the server response. But you cannot add new attributes in runtime. Your *.xcdatamodeld file compiles into *.momd and it contains all the data to create tables in the DB since Core Data by default works with SQLite under the hood and it's a relational database management system.
To make attributes optional you should check that.
And then newly created objects contain nil as default values of object properties. So, in your case your "youtube" property of Social object will be just nil.
Background:
I am using EF4 and ObjectContext. To optimze retrieval of complex object hierarchies, I manually execute database queries and then use ObjectContext.Translatey<T>(DataReader, entitySetName, mergeOptions.AppendOnly) to turn data rows into entities. I then attach the entities to the ObjectContext with Attach method. This also fixes relations between entities.
The problem:
After everything is loaded and set up I try to navigate from parent entity to a child entity (for example Parent.Childs.First()), but EF hits the database to load the kids, even though all the child entities are already present in the ObjectContext and EntitySet. It looks like the reason for this is that parent.Childs.IsLoaded is set to false which makes EF think that it still needs to load the relation.
Question:
How can I tell EF that EntitySet has already been loaded?
Is there a supported way to set RelatedEnd.IsLoaded to true. I wouldn't like to mess with the calling the RelatedEnd.SetIsLoaded internal method.
I found a smilar question here but it relates to DbContext and has no satifying answer ;-)
Matra
It looks like this was implemented in this change:
http://entityframework.codeplex.com/workitem/269
You can now iterate through your entities and tell them that their child collections are already loaded:
foreach (var entity in loadedEntities)
context.Entry(entity).Collection(a => a.SomeChildCollection).IsLoaded = true;
This will prevent entities in SomeChildCollection from being loaded when they are accessed from entity.
I'm not exactly sure what version of EF this appeared in but I'm guessing 6.0.0.
The only way to solve this is to turn off lazy loading. The question you have found on MSDN asks about DbContext but the answer mentions that there is no way to change the value in underlying libraries - ObjectContext API (= EF4 in your case) is the underlying library. Even in .NET 4.5 (EF5) setting IsLoaded is still not available on public API.
I have an entity (Org) in my Entity Framework that has a foreign key with a table that is in another database (BusinessUnit). We need the foreign key to get the description of the BusinessUnit linked with the Org. In the past (old project without Entity Framework) we were using a stored procedure to return all the information about this entity, including the BusinessUnit description, using a join. So now my problem is how to display the same information than before using Entity Framework.
I've tried, once I load my Org entity from database, to make a loop accessing to BusinessUnit to get the description for each Org, but this is too slow. My other idea was use a store procedure, but I need an extra field on my entity and Entity Frameworks gives me an 3004 error: No mapping specified for my property. I was thinking to use a complex type, but I'm not sure if it's what I need keeping in mind I have to add just a field to my entity. In that case, could I use the complex type just for "select" operations and keep my original entity for the rest of CRUD operations?
How should I proceed?
Thanks.
EF is not able to execute queries across multiple databases. If you need to perform such query you must either use database view and map the view as a new entity (it will be readonly - making it updatable requires mapping insert, update and delete stored procedures) or divide your data querying into two separate parts to load data from both databases. Divided querying can either use two contexts or you can get data from the second database using stored procedure.
The reason why you got the error is that you added the property in EDMX. EDMX can contain only properties mapped to your first database. EDMX generates entity code as partial classes If you need property manually populated from the second database you have to create your partial part (partial class) for entity and add the property in code.
I am lazy loading my entities and when I make an initial call to pull a list of entities I am seeing the System.Data.Entity.DynamicProxies....type. Which is fine and my entities map to my DTOs just fine. The issue I am having is that when I add a new item to my context it is being pulled fromt he context and not the database. So, I see the list being pulled back with the System.Data.Entity.DynamicProxies types and an my new item taht is the actual type of object.
So, for example I may have a list like this:
System.Data.Entity.DynamicProxies.Contact...
System.Data.Entity.DynamicProxies.Contact...
System.Data.Entity.DynamicProxies.Contact...
MyNameSpace.Contact
I created a custom type converter and noticed that the DynamicProxy types have a source value, but the MyNameSpace.Contact does not have a source value. So, it is not getting mapped in my type converter.
You can call the CreateObject/Create method in your ObjectSet/DbSet when you are creating the entity without using the constructor.
var newContact = context.Contacts.Create();
context.Contacts.Add(newContact);
The returned object is a proxy that supports lazy loading.
I am using Entity Framework 4 with the Service/Repository/EF4/POCO classes technique, and I have a question about View Model binding.
When you map a class to a view model and only take the fields the view needs, then map it back to a new instance of the class to persist to the database, how do you prevent the fields not used in the view from getting overwritten?
This is usually performed by loading entity from db first and merging incomming data to this entity (ObjectContext will track changes and update only changed properties). Another approach is manually set which properties where modified in state manager:
context.MyEntities.Attach(entity);
context.ObjectStateManager.GetObjectStateEntry(entity).SetModifiedProperty("Name");
Now when you save changes only Name property of the entity will be included in Update SQL command.
When using repostiory check high level example I shown here.