I am designing a database for storing products and some properties belonging to them. The properties can be inherited from parent product to the child product. For example:
ProductA ---> PropertyA, PropertyB
|-ProductB ---> PropertyC
In this example, ProductB should have PropertyA and PropertyB in addition to PropertyC. In order to get all the properties of a certain product, I need to go through all the parents and accumulate all the properties in a list. However, the Property class itself is a database entity, so can I use it to define normal objects (i.e. detached from database) without having them affecting the database contents, i.e. create, modify, delete instance as normal C# objects?
Yes you can. Entity Framework 4.0 onwards supports what is known as a POCO entity (Plain Old CLR Object). They can exist entirely separately from your database concerns and when appropriate you can attach them to an instance of an Entity Framework Context for persistence to the database.
Likewise you can Detach entities from a Context having retrieved them from the database through the same Context should you choose to manipulate them within your Domain Model in such a way that you don't want them persisted again.
Depending on whether you're doing true Code First or Database First will determine the development workflow you use for creating these entities.
Related
I have a general utilization question on how to set up Objectbox entities for wholly owned nested objects
My app has a central data entity 'Class1'. The 'Class1' entity includes an array of 'Class2' instances. The 'Class2' entity includes an array of 'Class3' instances. Both the 'Class2' and 'Class3' entities are fully owned by a single 'Class1' entity (i.e. they are never used or linked to anything else)
What's the best strategy for mapping wholly owned nested objects in Objectbox?
If I understand correctly, this can be done using relations in ObjectBox.
E.g. Class1 would have a ToMany relation property, Class2 a ToMany relation property.
https://docs.objectbox.io/relations#to-many-relations
We built a mechanism that on server request automatically retrieves the entities list from the DB, and maps them to ViewModels. We can't figure out how to support clearing View Models that are built from multiple DB entities when an update was made to some relevant DB entity.
This is how we've built our Cache:
We have a mapping between the key (the DB entity name) and the list of values it holds (View models).
This is how we handle entities invalidate:
On EF's Context Save method, we clear the Cache values by the saved entity's name (when it has been changed).
For most entities, all the Cache values are mapped to a single entity.
For some entities however, the Cache values depend on several other entities (which are either direct or indirect navigation properties of the entity).
For instance:
We have an EducationPlace Entity.
Its Cache key is "EducationPlace". Its values are a list of EducationPlaceViewModel.
EducationPlace entity has an Address property, and the Address entity, has a City property.
City's name is used in the EducationPlaceViewModel.
Now we want, that when the City entity is being updated, the Cache's EducationPlaceViewModel list will be cleared.
What we are looking for, is a way to update a cache entry, when an entity that the cache entry's View Model depends on is being updated.
The two solutions we've considered are:
Use reflection to find which entries should be cleared (by following the navigation properties). This will create many unnecessary dependencies, which will result in many redundant cache clears. For instance, EducationPlace has many navigation properties that are not being used by its View Model, hence should not trigger a Cache clear.
Use a custom Attribute that will decorate each relevant entity, and will hold its list of entities that its View Model depends on. This way we will easily get the entities that should be cleared when an entity is being saved at the Save method.
This way requires A LOT of maintenance. It requires for each new entity which its View Model depends on other entities for the developer to remember to use it on the new entity, and to update that entity when its View Model depends on new entities.
This is how we clear the View Models.
This method is invoked from the Context's Save method:
What this method basically does is:
It gets all the DB entities from the DAL layer
For each entity name, it:
a. Skips none-relevant entities
b. if the entity name exists as a Cache key - Clear its data
How can we tell Entity Framework about Aggregates?
when saving an aggregate, save entities within the aggregate
when deleting an aggregate, delete entities within the aggregate
raise a concurrency error when two different users attempt to modify two different entities within the same aggreate
when loading an aggregate, provide a consistent point-in-time view of the aggregate even if there is some time delay before we access all entities within the aggregate
(Entity Framework 4.3.1 Code First)
EF provides features which allows you defining your aggregates and using them:
This is the most painful part. EF works with entity graphs. If you have an entity like Invoice and this entity has collection of related InvoiceLine entities you can approach it like aggregate. If you are in attached scenario everything works as expected but in detached scenario (either aggregate is not loaded by EF or it is loaded by different context instance) you must attach the aggregate to context instance and tell it exactly what did you changed = set state for every entity and independent association in object graph.
This is handled by cascade delete - if you have related entities loaded, EF will delete them but if you don't you must have cascade delete configured on the relation in the database.
This is handled by concurrency tokens in the database - most commonly either timestamp or rowversion columns.
You must either use eager loading and load all data together at the beginning (= consistent point of view) or you will use lazy loading and in such case you will not have consistent point of view because lazy loading will load current state of relations but it will not update other parts of aggregate you have already loaded (and I consider this as performance killer if you try to implement such refreshing with EF).
I wrote GraphDiff specifically for this purpose. It allows you to define an 'aggregate boundary' on update by providing a fluent mapping. I have used it in cases where I needed to pass detached entity graphs back and forth.
For example:
// Update method of repository
public void Update(Order order)
{
context.UpdateGraph(order, map => map
.OwnedCollection(p => p.OrderItems);
}
The above would tell the Entity Framework to update the order entity and also merge the collection of OrderItems. Mapping in this fashion allows us to ensure that the Entity Framework only manages the graph within the bounds that we define on the aggregate and ignores all other properties. It supports optimistic concurrency checking of all entities. It handles much more complicated scenarios and can also handle updating references in many to many scenarios (via AssociatedCollections).
Hope this can be of use.
I'm building an iPad application where I need user to create entity dynamically. I'm already having 3 entities which program uses.
Could you help me with code how to do it?
I want to understand the whole structure according to my understanding I have to create new managedObjectModel, add new entities and than merge it with existing one, is it correct?
While it is possible to create a new entity and a new model on the fly in practice this is massively complex. If nothing else you would have to migrate any existing persisted data to the new model and a new persistent store file. I strongly recommend against attempting this especially if you are just starting out with Core Data.
You do have options:
Firstly, are you sure you actually need a new entity? People just starting out with Core Data often mistake entities for managed objects. Entities are to managed objects as classes are to instances. Entities are abstractions used to create the object graph. They don't actually contain data. The times when you need new entities are very,very rare.
Secondly, if you do need some kind of dynamic entity, it would usually be best to decompose the dynamic entity into numerous fixed subentities and then use relationships to create a virtual entity. E.g. you need a dynamic Person "entity" so you create several entities in the model each of which holds one attribute of the person. You could have a Field entity which would have a fieldName attribute and then a fieldValue attribute. Then have a an actual Person entity that has no attributes but just relationships to the necessary Field objects. You could add any fields needed to any person and then reconstitute an virtual person object by walking the relationships to its fields.
I rather doubt however that you need that kind of flexibility. Such a need is very rare. I would step back and see exactly what dynamic data you think the user might need to enter.
That's correct -- you'd create an array of NSEntityDescription objects, then call setEntities: on the new managed object model. Then, finally, you'd merge that model with your built-in model.
But note that you can't change a model once it has been used to create a managed object context (or used for storage). You'll need to create new storage and context after the model is changed.
In the past I used Sub Sonic which has the activerecord pattern baked into the framework. With Sub Sonic it was very easy to find the "dirty" fields on an update. I now have a need to create an audit table in my application that utilizes Entity Framework 4. Is there a comparable feature in EF 4 that will give me the dirty fields?
Thanks for your help!
You can get similar functionality with what is described in this page at MSDN:
Identity Resolution, State Management, and Change Tracking
Change Tracking -> Change tracking
information for the object graph is
stored in ObjectStateEntry objects,
which are created by the ObjectContext
for each attached object.
ObjectStateEntry objects store the
following information for the
entities:
...
The names of the entity's modified
properties.
Entity State -> The object context must know the state of an object to
save changes back to the data source.
ObjectStateEntry objects store
EntityState information. The
SaveChanges methods of the
ObjectContext process entities that
are attached to the context and update
the data source depending on the
EntityState of each object. For more
information, see Creating, Adding,
Modifying, and Deleting Objects. The
following table shows the possible
states of an object.
The state of objects inside an object context is managed by the ObjectStateManager. To find out the state of an object, call one of the following ObjectStateManager methods: TryGetObjectStateEntry, GetObjectStateEntry, or GetObjectStateEntries. The State property of the ObjectStateEntry defines the state of the object.
Take a look at this article for more info:
What's New and Cool in Entity Framework 4.0