In SDN3.4.0 when an entity is loaded from database, empty child objects (no #Fetch annotation) are populated with only ids present. In SDN4 this doesn't happen and child objects are not populated with ids (for depth 0). Wanted to understand the reason for this change ?
Is there a way to directly populate child objects in SDN4 when entities are queried using complex cypher queries either from session or repository (using #Query).
The default load level is 1 when using the session or repository load methods. This means all objects directly related to the entity are loaded.
You can override this depth.
#Query does not support depth specification at the moment.
Related
I'm having a weird (or at least unexpected) problem with Breeze. I have an EF back-end view model to which I send some parameters and it returns some data. I use the withParameters option to do this. The back-end does a lot of Includes and projection and returns the data I want to display in a set of custom view model entities (i.e., not database entities). One of the parameters is a list of keys for which I want to display data.
The keys identify which children of the parent entities I want to retrieve, though I am retrieving a list of parents (e.g. keys [1,2] mean it should get all Parent entities with a Children list property that themselves have a ToyId property that has a value in keys and those Child entites). In other words, the structure is like Parent.Child[] and Child.ToyId and I want to get parents with children that have certain toys and those children themselves (but not other children). Both parent and child sets are large so I do this in SQL via EF (which was an adventure in itself).
Anyway, the problem happens after I select two keys and get the data and then de-select one of the keys. The first query, getting the data for two keys, works as expected. On the second executeQuery's callback, I get the same data as the previous query, meaning it's as if I never de-selected the key. I've verified that Breeze hits the back-end with the correct keys parameter value and the back-end returns just the data I want, but it seems that Breeze is ignoring the data from the back-end or performing a union on the result set from the back-end and its cached entities (for both keys) and sending that union as results into the callback instead of just what the server returned. Is this expected behavior? Unfortunately everything is written this way. We (working on this, our first project using Breeze) all assumed it would only return what the server sent when not using executeQueryLocally, so it will be a big deal to refactor. Sigh.
I tried some where predicates which didn't work and don't see how projecting on the Breeze side would help either. I thought maybe it saw the query as identical so it returned cached data as a shortcut, so I added a where('Parent.Children', 'any', 'ToyId', 'in', keys), but that didn't work, it still brings in the de-selected results.
The only way I've found to get around this is via queryManager.clear() before I make any of the queries, and I suspect doing a noTracking query might work also (albeit without actual entity objects). I thought about converting the keys parameter into a where filter and sourcing it from there instead of the keys parameter, in case that would tell Breeze to only show the back-end data.
Is there a "correct" way of getting back only the data the server sends in the callback?
("The callback" meaning the function passed into executeQuery.then(...))
As you've noticed, Breeze merges the query results into the cache before calling your callback method. This means that, in the callback, a parent entity will have all of its children that exist in the cache.
The array of entities returned by the query is available in the retrievedEntities property of the saveResult object returned in the callback. You can use this to determine which children were returned from the query.
entityManager.executeQuery(query).then(function(data) {
var parents = data.results;
var ret = data.retrievedEntities;
//... filter ret to get the children
//... update viewmodel with children
});
I am using coredata to save the server data through web services in my application and I am storing relationships as an object to the entity.
I have many entities e.g "Inspirations" and "Products" and both are related to each other. I have a problem whenever the records are updated in the third entity which is "Filters" then the relations of the entities broke and I cannot apply filters on the entities.
[object addRelatedInspirationsObject:related];
This is how I save relationships. I am not able to figure out why the relations are being broken once the entity is updated which has no direct link with the entity.
One thing more if I fetch and save the data of any one of the entities like "Inspirations" then all the relations start to work again.
Your code should work. Here are 2 things you need to check:
Make sure related is not nil when you call your method.
Make sure you call save on a valid managed object context.
From your question it seems that entities have 1 to many relationship between them. And by the code you supplied, every things should work fine. Just make sure, you are using the Filter object from the relationship like object.filter (or obj1.obj2.filter), not accessing it via a direct NSPredicate on Filter entity and updating it. And if you are using FRC, you might also need to generate a fault against the parent entities, to get your UI updates.
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'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.
When getting an object from the DB, should the object's properties also be loaded? There seems to be these approaches.
Create well-formed, fully-loaded objects.
Pro: No need to check if a property has been loaded; it has. Pass it around and don’t worry about parts of the object not being there.
Con: Where do you stop? If an object has an object, and that object has an object, and that object has 40 objects as properties, etc… Do you load the whole DB? Or do you make a decision in the BLL as to what constitutes a well-formed object, and load those properties?
Don’t load any properties that are other objects.
Pro: Quick, no loading unnecessary properties.
Con: Code has to be constantly written to check if properties are populated.
Lazy-loading: only load properties when they are first used.
Pro/Con: Not sure what to say about this approach. It seems intuitively wrong.
Is there another approach? What approach is the best?
And finally, what about properties that can be null? For example, a car may not have a PreviousOwner object. Do you set it to null? An empty PreviousOwner object? Does that property belong in another class then?
There's no easy answer to your question because it depends on what you're trying to achieve.
It looks like you expect a more or less complete object graph to be loaded from the database (i.e. with relationships between multiple object types and the objects themselves stored in the database).
If this is the case, I would look into using the Object Relationship Mapper that's convenient in my language of choice.
As to how much of the object graph is being loaded, the model employed by Apple CoreData's system is objects not yet retrieved are marked as faulty (they call the concept "faulting" - it's described in Limiting the Size of the Object Graph: Faulting. This is a play on the lazy loading concept you described yourself.