I've two entities, which are linked as one to many.
I want get the dependent entities by primary key of the main entity.
Scenario 1
I'm calling to the dependent entity and getting this by foreign key.
Something like context.dependentEntity.where(entity => entity.foreignKey == PKMainEntity)
Scenario 2.
I'm calling to the main entity and getting dependency entities.
Something like context.mainEntity.find(PKMainEntity).select(x=>x.dependentEntity)
The primary keys have indexes by default;
What scenario is faster?
In Scenario 1 you fetch everything you need an nothing you don't. So this is the preferred way.
In Scenario 2 you have two database calls. It's identical to
var entity1 = context.mainEntity.find(PKMainEntity);
var dependents = entity1.DependentEntities;
The second call loads the dependent entities by lazy loading.
A third way is
context.mainEntity.Where(entity => entity.Key == PKMainEntity)
.SelectMany(e => e.DependentEntities)
This will also execute one query. It's even likely that EF will make it identical to the first query. This form may come in handy when the dependent entity doesn't have a back reference to the the main entity.
Also for many-to-many associations this is an efficient way to get the "many" entities of a root entity (for example, the categories of a product).
Related
I have 2 entities in which totally 12 properties are there of 3 variations of min, max and average of some particular type of fields. Hence I refactored the 2 entities into 3 entities making the 3rd entity as 'Values' which contains 3 properties i.e min, max and average. And reduced the 12 properties into 4 relationships. Here's a replica of my models as an example in the image below.
As you can see I have one-to-one unidirectional relationship with the 3rd entity. However Xcode keeps on complaining about 'Inverse' relationship.
As per me I can add 4 relationships in 'Values' and update all to become 'inverse', however this doesn't seem to be the right solution as when the second entity gets tied to the 'Values', it will have additional 3 nil relationships and whereas in case of first it will have 1 additional nil relationship. Both of these are unnecessary.
Refactoring 'Values' and splitting it into two similar entities also is not a good solution either I believe.
Hence can anyone suggest me what is the right approach or best practice to solve this problem. Let me know if I'm unclear anywhere while describing my issue.
Based on your description, I would undo the refactoring and go back to using properties instead of relationships. You're adding complexity for no real benefit, and the Values entity is (as you're finding) too generic to really be useful or meaningful. This refactoring isn't serving any useful purpose; don't fix it, revert it.
You should look into Weak Relationships (Fetched Properties) for how to manage relationships correctly and the solution for your error code.
Most object relationships are inherently bidirectional. If a
Department has a to-many relationship to the Employees who work in a
Department, there is an inverse relationship from an Employee to the
Department that is to-one. The major exception is a fetched property,
which represents a weak one-way relationship—there is no relationship
from the destination to the source.
Also, if you want to make things easier, you should look into (if possible) avoid 3 objects and have a single object, or two objects, with the propertiesToFetch of the NSFetchRequest in mind. This way you can fetch your Entity , keep the properties in a single Entity, but only fetch the properties you want and avoid the overhead and memory consumption of fetching properties you are not going to use.
Whichever fits your needs, you have the options. GL
In my project, I have an entity, Task. I was going to create another entity, Subtask, and assign a one to many relationship from Task to Subtask, meaning one Task can have many Subtasks.
However, upon mapping it out, I've realized that the Subtask entity is identical to the Task entity, as far as its properties. They are the same, only difference is one is a parent of the other.
Would it be better to create a one to many relationship with no inverse, (subTask property) as shown:
Or would it be better to create another object, and set the relationship as so:
Or would it be better to create a parent property and a child property in the Task entity, and set the relationship as so:
I think the last method is the best but I am not sure, any direction would be wonderful.
If the two entities would be identical except for the parent/child relationships, then a to-many relationship from an entity to itself is the way to go. No sense creating two copies of the entity when one will do. If those two entities are (or might ever become) different in any other way, keep them separate.
I have EntityA which has a navigation property to EntityB. In the frontend it's possible to create a new EntityA and append it to EntityB. If I now try to save the new created EntityA, Breeze also want's to save the changes on EntityB (containing the new ID of the newly created EntityA). Is it somehow possible to avoid having EntityB, because in this specific use case it should be possible to append new entities to EntityB, but these should not be saved back (and also not be reported as pending changes)?
I see the possibility with using two EntityManagers, but this would mean that I can no longer have navigation properties between the two types.
Pascal is asking an important question: are Entity A and Entity B related one-to-one? More to the point are they related one-to-one such that A depends on B (i.e. A is a child of B)?
A typical relationship of this sort is the "extension" entity. Consider "Order" and "OrderExtension". "OrderExtension" is a bolt-on type with optional fields that "extend" the core order data. An order can have zero or one "OrderExtension" records.
Order is the parent in this example; it SHOULD NOT have a FK reference to the OrderExtension. The OrderExtension is the child and it SHOULD HAVE a required OrderID FK field. The parent Order can exist without a child, but the child OrderExtension cannot exist w/o the parent.
At least that's how I think it should be. I've often seen folks turn this around. They give the Order an OrderExtensionID FK field which is optional. The OrderExtension has no backpointer to the Order.
The weakness of this design is that it allows you to create multiple orphaned OrderExtension entities that don't belong to anything ... and you'll rarely know they are there.
I'm betting that's your situation. I'm betting that Entity B is like OrderExtension and Entity A is like Order. When you created the OrderExtension (B) and associated it with an Order (A), Breeze tried to maintain that relationship for you by updating the Order.OrderExtensionID property. That puts Order (A) in a modified state.
DO not proceed until you've figured this out. While Jeremy is correct that you can save one entity by cherry picking the pending changes - you can save B without saving A -, you risk breaking the integrity of your data!
From a modeling perspective you've made Entity A dependent on Entity B. If you don't save A at the same time you save B, there will be no way for someone using the database to know that the two are related.
Next time you query for either of them, neither you nor Breeze will know they are related. You will be unable to navigate between A and B. I'm pretty sure that's not what you had in mind.
You can pass an array containing the entities you wish to save to the saveChanges method to restrict which entities are saved.
From the breeze docs:
saveChanges ( [entities] [saveOptions] [callback] [errorCallback] ) async
Saves either a list of specified entities or all changed entities
within this EntityManager. If there are no changes to any of the
entities specified then there will be no server side call made but a
valid 'empty' saveResult will still be returned.
Parameters:
[entities] Array of Entity optional The list of entities to save.
Every entity in that list will be sent to the server, whether changed
or unchanged, as long as it is attached to this EntityManager. If this
parameter is omitted, null or empty (the usual case), every entity
with pending changes in this EntityManager will be saved.
I'm struggling with creating a suitable Core Data model for my app. I'm hoping someone here can provide some guidance.
I have two entities -- "Goals" and "Items". The Goals entity contains only a goal description, but any goal may have any number of subgoals, and these may extend multiple levels in a tree structure. Subgoals are to be contained within the same entity, so presumably the Goal entity will contain a pointer to "parent" which will be the parent goal of any subgoal.
There will also be an "Items" entity that contains a couple of text fields and a couple of binary items, and must be linked (ideally, by a unique identifier, perhaps objectID) to the particular goal or subgoal the item(s) are related to.
I am totally fumbling with how to set this model up. I know what attributes need to be in each entity, but the relationships, particularly between goals and "subgoals", has me stumped. I don't seem to be able to turn up any good examples of tree structures in Core Data on the Internet, and even the couple of books I have on Core Data don't seem to address it.
Can anyone here help an old SQL programmer get headed the right direction with these relationships in Core Data? Thanks.
Have you tried creating a one-to-many from Goal to itself, and a one-to-one from Goal to Item? The only thing I would worry about here is circular references.
Also, read Relationships and Fetched Properties in the CoreData Programming Guide.
Here is how it is done:
You set up a to-many relationship from Goal to Item in the model editor. Don't use any ids, foreign keys etc. This is old-fashioned database thinking - you can forget about it. Here we are only dealing with an object graph. The database layer is just an implementation detail for persisting the data.
Make two more relationships in entity Goal to itself: a to-one called parent, a to-many called subGoals. Make them the inverse of each other. Simple!
QED is correct, you can create a to many relationship on goal (call it subgoals) as well as a to-one relationship on goal (call it parentGoal) and set them as inverses to each other.
Then create another to many relationship (call it items) on the goal entity, with the inverse being a to one relationship on the item entity (call it goal). Then you're all set. You don't need to link items with a unique id, just add them to the items relationship.
Also note that if you did want to give items a unique id, do not use the objectID. The objectID should only be used as a temporary id as they are not guaranteed to remain the same. In fact they will change if you ever do a Core Data migration.
One way, though not really great, is to create a another entity, say subGoal, and each goal has one subGoal and each object of subGoal has many goal.
I am just getting started with Microsoft's Entity Framework, using it for an MVC project since MS seems to be really pushing it, and I'm running into some issues. In my database there are multiple lookup tables tied to a single table via foreign keys. Within the entity framework I am trying to combine these into one so that I have a simplified single view for this data in my model. However, this doesn't seem possible from the designer view. Is there something obvious I'm missing? Is there a way that I can edit the edmx file manually to produce this sort of model?
At the moment, Foreign keys and lookup tables in Entity Framework are a PAIN.
EF with LINQ makes getting your data super-easy, and on the surface it looks easy to update, but with lookup tables things get difficult (for now... read on...)
I'm not sure how you would "combine" your lookup tables into a single table. If each table contains a different type of "lookup entity" then IMHO they should be represented separately in your EDM. I'm guessing you're having headaches updating a record's foreign keys to the lookup tables. That's because it is a headache.
Changing foreign key values:
MyDBEntities _db = new MyDBEntities();
//get a Person
MyDBEntities.Person person = (from p in _db.Persons
where p.Id = 1
select p).First();
// This sets the foreign key value in the Person table on the PersonType field
person.PersonTypeReference = new EntityKey("MyDBEntities.PersonType", "PersonTypeId", 3)
The next release version of the Entity Framework will have a new concept called "FK Associations." This will bring back the sanity of setting the foreign key value directly rather than having to create and set an EntityKey.
HTH.