Looks like I am stuck with decision of planning my Core Data model structure because I am not understand enough clear how Core Data need to work in my case. Now I have an entities Customer and City . Each with few properties in them and without relations between them now. They both have many relationships with other objects, so they are fully independent kind of objects. In my Customer entity I have city property (in what city customer is located). It's value needs to match to value of property name (name of the city)in City entity. Scheme looks like this:
Objects to what City is an alias are formed by parsing JSON file from web and now this part works fine. I added a method in NSManagedObject subclass(generated from entity)for Customer to retrieve the name property value from City entity and store it in city property:
- (City *)city
{
return (City *)[[PTDataFetchHelper sharedInstance] entityForName:#"City" withServerID:self.city_server_id inContext:[self managedObjectContext]];
}
This works without relations, but my UITableView (I am using NSFetchedResultsController like source)start to work horribly slow with this kind of fetching. Also I understand that using this scheme I cannot implement search by both Customer and Cityobjects - I can fetch only from one kind of entity. I found that I can create parent entity for this two, but they are logically and structurally independent. What is the best architectural way to solve this two problems?
Any comments appreciated.
A few observations:
You've made a deliberate effort to avoid setting up a relationship between City and Customer in the model. I'm not sure why based on what I understand about your requirements. You make the comment that you "added a method in NSManagedObject subclass for Customer to retrieve the name property value from City and store it in city property." but that's not what it seems you're doing. You've created a getter method for the city property on Customer that dynamically fetches the city name from the context each time it is called. This may be the cause of the slowness you report.
You can create an NSFetchRequest that traverses relationships. Look into:
KVC collection operators
Predicate format syntax
Customer and City are not actually logically independent because customerInstance.city must always be a name that is a cityInstance.name as you have it structured now.
Related
I have a core data design with multiple tables using relationships. My database is SQLite. For updates I import data from JSON and use this method:
[NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context].
I have added unique constraints in core data.
If I update an entity that is a relationship of another object it loses the connection.
Ex: Entity "person" that contains the one to one relationship to "pet_id". If I update "pet" it changes his id and "person" still points to the old id, so they are not related any more.
Is there a way to avoid this problem?
I don't think this is documented anywhere yet. Here's what it sounds like is happening:
You create a new instance. Your constraints mean that this instance matches an existing instance. But...
Your new instance has a nil value for this relationship. So...
The existing instance's value for the relationship is replaced by this new nil value.
To maintain the relationship, your new instance needs to already have the correct value for that relationship. You're essentially asking that the constraint matching system ignore the fact that the relationship value is different in your new instance, but to accept new values for other attributes.
I think what you're expecting is completely reasonable but I'm also not surprised that the current implementation doesn't support it. I recommend filing a bug with Apple about this, and investigating non-constraint based approaches to keeping your data unique.
I am struggling with something I think should be basic but cannot figure out. I have two entities in core data with a one to one and one to many relationship. They are Company which can have multiple Opportunities.I want to load a table view listing the opportunities (sorted by name) with their associated companies. Can this be done by simply accessing the Opportunity entity? If so, how do I access company? The Opportunity class references it as a "Company" type and so I tried to go using dot notation through to company.companyName but it failed on that, and if I change it to simply company (of type Company) it does show .Company: and other reference data but not the simple name field I am looking for. This seems as if it should be simple but...........
This was simple and I was overlooking the ability to load the fetchedresultscontroller with the right type (in my case the Opportunity class) and then use dot notation from there. I was trying to do it with key value access which did not work. Cheers
We have identified a Location entity in a database as a value object in our domain (DDD). Locations are used by other domain objects, but don't really "stand alone" -- they always belong to another entity.
Now we are trying to edit a list of these values in a simple MVC web application. So the view would show a list of locations in a view model LocationViewModel.
However, the value object is by definition immutable, yet does hold a reference to another entity (Business).
Domain:
public class Location : ValueObject<Location>
{
readonly locationId;
public int LocationId {get{return _locationId;}}
public Business Business {get;set;}
}
My problem is understanding how you can simply edit a bunch of value objects in a UI and change, e.g. what Business the location belongs to.
A value object is not supposed to have an "identity", but it does need an ID so the repository can update the database.
I also don't think you can make Location an entity just because you want to edit it in the UI. Or is Location, in this scenario indeed an Entity?
What am I not understanding?
Thank you!
It's a classic problem. In one context it's an entity and in another a value object. I found the example of a telephone number helpful to understanding this sort of problem.
In a CRM for example, a telephone number is a value object. The same one can be associated with multiple contacts. It varies by value (key concept here). So in this context it's a value object. In this example, I could store telephone numbers in the database and the 'ID' would be the telephone number itself. If the value object was made up of multiple parts then they would form a composite key.
If however we looked at a telephone number at a telephone company. That would most likely be an Entity. It could have all manor of information attached to it. All that info would vary by ID (which in this case would be the number).
In your case, Location sounds like a value object. If you need to save it in a database as a thing rather than just as part of an entity then use it's parts as a composite key. You will need to handle what happens when you 'change' one as it's not a change but the creation of new value object. One approach is to remove the old and insert the new. Or just keep all versions. It depends on your domain.
Hope that's helpful.
You don't change a value object. You create a new one with different values. If the value object has few properties that you want often to change, some helper methods are usefull. myObject.WithX(4711) will create a new instance with all properties the same as myObject but the X Property changed to 4711 for example.
To "edit" a value object in an UI you use a viewmodel. The Viewmodel is not a value object (and no entity by the way) and is not part of your domain. It's purely in the Presentation Layer. It is editable and mutable. It could have a constructor, taking your (immutable) value object to copy its values from and it could have a ToXXX Method to create a new (immutable) value object with its current (and changed) values.
If you want to store your value objects in a separate table (instead of roll out the fields in the table that stores the owning entity) this is purely data access layer related and not part of your domain model. This could be done by mapping. In the value object the database id is immutable and has no meaning in the domain model.
I am using entity framework and developing an architecture for application with remote data access. Coming back to point, i query the database for one record (say on the basis of itemcode). Now the resultset i will get whether i should return it as List or collection or simple as an object of entity. I am using entity object but my boss is saying i should use List. He thought , returning result as an entity with return whole table structure also. Quick suggestion would be appreciated.
List<Employee> lstemployee = GetRecordByCode(itemCode)
or
Employee emp = GetRecordByCode(itemCode)
What's the difference? If itemCode is a unique key you will either get one Employee object or a list containing the same one Employee object. You will never return the whole table. That will only happen if within GetRecordByCode you do something like context.Employees.ToList() without any Where filter before the ToList().
If itemCode is not unique you even have to use a list.
Say, I have my coredata structured to something like this...
Class
classID <- RestKit primaryKeyAttribute
name
time
students (relationship 1-to-many)
Student (nested in Class)
studentID
name
class (inverse relationship) <- RestKit primaryKeyAttribute ** this doesn't work?! **
I specifed primaryKeyAttribute of the mappings as shown above. When I send a load request using restkit, it will correctly update object with the same primarykey. RestKit seems to update the class correctly, but for students, it just adds new ones and nullify the class relationship of old students. So now I have unwanted student entities in db with no reference to class.
Is there a way I can use RestKit to update the students relationship correctly? Btw, I thought about using studentID as primaryKeyAttribute instead, but it may not work correctly if have some students removed in the new updates. May be I have to clear all students for the class before updating, but I also don't know how to do that in RestKit. Because by the time RKObjectLoader didLoadObject is called, seems like everything is already saved to the managedObjectContext. Any ideas? :(
Still can't find a RestKit-way solution, and doesn't look like there will be anyone who can answer this :-\ So I'm posting the best approach I can come up with.
My current work around is to iterate through class' students and manually delete them in objectLoader:willMapData:. I have to do here (not in objectLoader:didLoadObject:) because it is the place where the new data is not saved into MOC yet.
You can also delete the Class entity entirely, but that way doesn't actually updates the old one. It creates a new one with a new "core data internal _pk" (primary key) (yes, I do care about it).