I have an App using a sql base. I created this base with 1 Entity, 10 Attributes at the begining.
So, now I have to add new attributes. (4 more), so I did the versioning, model ... update.
Then, I changed my App in order to access to my new fields values. But, what I don't understand, is how my App can access to my new field in the updated sqlite data base.
Certainly doing something wrong but honestly don't know.
Whether you're using SQLite or not makes absolutely no difference here. Similarly, if lightweight migration is working (i.e. the store is being opened successfully) then there's really little more to say about that.
Assuming you're using NSManagedObject subclasses then what you've probably not realised is that merely updating your model doesn't update the classes you generated for it. So you need to do that again. It'll add the new properties to the relevant classes.
You could write a quick test using key-value coding to demonstrate that the fields are there — e.g.
NSLog(#"%#", [object valueForKey:#"newProperty"]);
... but you should probably stick to generating new class definitions and using the runtime-synthesised getters and setters that flow from there, as it'll allow the compiler better to verify what you're typing and will lead to more efficient code at runtime.
Related
I've inherited an MVC 3 project that uses AutoMapper. It appears to use nothing but the default Automapper configuration (I can't find any other configuration for Automapper anywhere in the solution, in other words). So I've written code like this for two new models I've added to the project:
Mapper.CreateMap<Entities.Document, Models.Attachment>();
Mapper.AssertConfigurationIsValid();
return Mapper.Map <List<Entities.Document>, List<Models.Attachment>>(Attachments);
Which ought to work fine - but the problem is that Automapper fails because of an inability to map completely unrelated objects. In other words, I get this message when Mapper.Map is called:
The following 2 properties on MyApp.Models.User are not mapped:
IsAdminUser
SubRoleList
Add a custom mapping expression, ignore, or rename the property on
MyApp.Entities.UserProfile.
Why is the mapping failing when Models.User has nothing to do with the models I'm mapping? They don't inherit from it. They don't contain any references to it. My new models are very simple models that contain a few strings and ints. MyApp.Models.User doesn't rely on them for anything, either.
I realize this problem can be solved by specifying the mappings in my AutoMapper calls. In fact, I've already done so, and it solves the problem. So I'm not worried about that. I can move on. What I'm worried about is that I can't figure out for the life of me why I'm getting this message when I try to use the default mapping. There are many other objects in the app which are very similar to the new objects I'm trying to map. They all work perfectly when code like the above is called. They don't require specifying any mappings and they don't have problems with MyApp.Models.User. I just want to know WHY this is happening because I want to understand it. Anyone got ideas? In case it's not obvious, I'm relatively new to MVC and Automapper. Thanks. :)
EDIT: Additional information:
If I add a call to Mapper.Reset() before the call to CreateMap(), everything works perfectly. I still don't understand why my method is the only method in the app that needs a Reset first.
We're looking for a way to document Core Data entities. So far the only real options I've come up with are:
Document externally using UML or some other standard
Create NSManagedObject subclasses for every entity and use code comments
Use the User Info dictionary to create a key value pair that holds a string comment
Option 1 feels like too much extra work and something that will almost certainly be out of date 99% of the time.
Option 2 feels natural and more correct than option 1. The biggest con here is that those comments could potentially be lost if this model class is regenerated using Xcode.
Option 3 feels a little less correct than option 2, but has the added advantage of adding automation possibilities with regards to meta data extraction. For instance, in one of our apps we need to keep a real close eye on what we're storing locally on the device as well as syncing to iCloud. Using the user info dictionary it's pretty easy to automate the creation of some form of artefact which can be checked both internally and externally (by the client) for compliance
So my question is whether it would be inappropriate to use the user info dictionary for this purpose? And are there any other options I'm missing?
Option 2 is what I use every time. If you look at your core data model (something.xcdatamodeld or something.xcdatamodel) you will see something like the picture below.
You can tie your entity to whatever class you want and then put the comments in there. It helps if you keep your entity name the same as your class name to make it obvious what you've done.
Additionally this also gives you the ability to add automation. You can do this by creating custom getters and setters (accessor methods) and a custom description method.
I use option 2 and categories. I'll let XCode generate the NSManagedObject subclasses and use a categorie on each of these subclasses. With the categories I do not loose my changes made in the categories, can document, make custom getter and setters and I am still able to use generated subclasses.
If we speak only about documenting (i.e. writing more or less large amounts of text which is intended to be read by humans) your classes, I'd use the option 2.
If you are concerned with the possibility of Xcode overwriting your classes in the option 2, you may consider creating two classes for each entity: one which is generated by Xcode and always could be replaced (you generally do not touch this file) and one other which inherits from the generated one and in which you put all your customizations and comments.
This two-class approach is proposed by the mogenerator.
Although if you need to store some metadata with the entities which will be processed programmatically, the userInfo is perfectly suitable for this.
I have an existing database, which I have been happily accessing using LINQtoSQL. Armed with Sanderson's MVC3 book I thought I'd have a crack at EF4.3, but am really fighting to get even basic functionality working.
Working with SQL 2008, VS2010, the folder architecture appears to be:
ABC.Domain.Abstract
ABC.Domain.Concrete
ABC.Domain.Concrete.ORM
ABC.Domain.Entities
Per examples, repository interfaces are abstract, actual repositories are concrete. Creating EDMX from the existing database puts that in the ORM folder and the Entities holds the classes I designed as part of the domain. So far so good.
However! I have not once persuaded the deceptively simple EfDbContext : DbContext class, with method to work...
public DbSet<ABC.Domain.Entities.Person> Person { get { return _context.Persons; }}
It complains about missing keys, that Person is not a entity class, that it cannot find the conceptual model, and so on.
Considering I have a basic connectionstring in the web.config, why is not creating a model on the fly to do simple matching?
Should the ORM folder exist, or should it simply be Concrete? (I have a .SQL subfolder for LINQtoSQL concret so it suits me to have .ORM but if it's a flaw, let's fix it).
Should I have my homespun entities AND the automatically produced ones or just one set?
The automatic ones inherit from EntityObject, mine are just POCO or POCO with complexTypes, but do not inherit from anything.
What ties the home designed Domain.Entities.Person type to the Persons property of the Context?
Sanderson's book implies that the matching is implicit if properties are identical, which they are, but that does not do it.
The app.config has an EF flavoured connection string in it, the web.config has a normal connection string in it. Which should I be using - assuming web.config at the moment - so do I delete app.config?
Your help is appreciated. Long time spent, no progress for some days now.
What ties the home designed Domain.Entities.Person type to the Persons
property of the Context?
You seem to have a misunderstanding here. Your domain entities are the entities for the database. There aren't two sets. If you actually want to have two sets of object classes (for whatever reason) you must write any mapping between the two manually. EF only knows about the classes which are part of the entity model.
You should also - if you are using EF 4.3 - apply the DbContext Generator T4 template to the EDMX file. Do not work with EntityObject derived entities! It is not supported with DbContext. The generator will build a set of POCO classes and prepare a derived DbContext. This set of POCO classes are the entities the DbContext will only know about and they should be your only set of domain entities.
The created DbContext will contain simple DbSet properties with automatic getters and setters...
public DbSet<Person> People { get; set; }
...and the Person class will be created as POCO as well.
Download the entity framework power tools:
http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d
Right click in your project to 'reverse engineer an existing database' it will create the code classes for you. No need to use EDMX ,and this method will create the DbContext derived class for you
There are many questions here and you won't get an answer, but I'll stick my 5 pence for what it's worth.
Sanderson's MVC3 book
Your problems are not to do with MVC3, they are to do with Entity Framework and data persistence layer.
ABC.Domain.Abstract ABC.Domain.Concrete ABC.Domain.Concrete.ORM
ABC.Domain.Entities
Can you say why this is separated in such a way? I would argue and say that ABC.Domain should contain your POCOs independent of your persistence layer (EF) and your presentation layer (MVC). Your list implies that your domain contains ORM and your data access entities. I'm not arguing here, what I'm trying to say, is that you need to understand what you really need.
At the end of a day, I'm certain that a simple example would suffice with ABC.DataAccess, ABC.Domain and ABC.Site.
Do you understand why repositories are abstract and concrete? If you don't, then leave out interfaces and see whether you can improve it with interfaces later.
Person is not a entity class, that it cannot find the conceptual
model, and so on.
Now, there are multiple ways you can get EF to persist data for you. You can use code first, where, as the name implies, you will write code first, and EF will generate database, relations and all the relevant constraints for you.
You can use database first, where EF will generate relevant class and data access related objects from your database. This is less preferable method for me, as it relies heavily upon your database structure.
You can use model first, where you will design your class in EDMX designer and it will then generate relevant SQL for you.
All of these might sound like a bit of black box, but for what you are trying to achieve all of them will work. EDMX is a good way to learn and there are many step by step tutorials on ASP.Net.
but if it's a flaw, let's fix it).
You will have to fix and refactor yourself, there is no other way to improve in my honest opinion. I can give you a different folder/namespace structure, but there will always be a "better" one.
Should I have my homespun entities AND the automatically produced ones
or just one set?
Now this depends on the model that you have chosen. Database first, code first, code only and whatever else is there. If you are following domain driven development, then you will have to work with classes, that represent your business logic and that are not tied up to your data persistence layer or presentation layers, therefore POCO is a way forward.
What ties the home designed Domain.Entities.Person type to the Persons
Now this again depends on the model that you are using.
The app.config and web.config
When you are running your web application, the connection string from web application will be used. Please correct me if I'm wrong.
Your help is appreciated. Long time spent, no progress for some days
now.
General advise, leave MVC alone for the time being. Get it to work in a console application and make sure you feel comfortable with options offered in EF. Good luck :)
The solution to why nothing worked code-first...
...turned out to be a reference to System.Data.EntityClient in the connection string, which ought to have read System.Data.SqlClient.
Without this provider entry being correct, it was unable to work code-first.
Finding which connectionString it was using was a case of deliberately mis-spelling a keyword in the connections there were to choose from - they all were named correctly - but were in app.config, and 2 places in the web.config. With a distinct naming error, when the application threw an error trying to create the domain model, it was easy to identify which connection string my derived DbContext class was using. Correcting the ProviderName made all the difference.
Code-first is now working just fine, with seeded values on model changes.
Xcode auto-generates the class implementations for your NSMO entities - great.
But we often need to customize them. If you ever forget that you customized these files, Xcode will happily "delete" (overwrite) and remove all your code.
So ... a classic trick was to:
Create the NSManagedObject's in Apple's model view
Generate the classes
Create new classes which use Categories to extend the original classes, adding the modified behaviour
Import the custom-category-headers rather than the base NSMO headers, thereby getting the "new" behaviour
This works great: put custom code in the category, and when you auto-generate files using Xcode, you never lose anything.
But ... now I'm using Bindings / Mac OS code, and Bindings are great, but I have no idea how to make a Binding "import" the derived header (with the category, and the modified methods / custom behaviour)?
e.g. if I have an ArrayController (very common) that's holding NSMO instances, you normally tell it the "Entity Name" (e.g. "MyCoreDataEntity"), and it requests the NSMO with that class name. But that will never load the category, so it will never pick up the customized version of the class.
How do you get around this? Either: how do you load in the category-version of a class?
OR: how do you write custom code without using categories and AVOID Xcode deleting all your code when it feels like it?
I must admit since I use cocoa touch there is no binding available - so I really do not know if my suggestion is applicable in your case.
However, maybe this helps?
There is an alternative to categories for core data additions - not as "sophisticated" as categories - I know.
One may use #include statements:
There are two alternatives:
create a new ClassFile, delete the include "header.h", (delete the header.h), put the extra code there. It compiles but brings the two warnings: (which are understandable) [WARN]warning: no rule to process file '$(PROJECT_DIR)/Classes/../included_dataStuff' of type text for architecture armv6 [WARN]warning: no rule to process file '$(PROJECT_DIR)/Classes/../included_dataStuff' of type text for architecture armv7
create a new "empty" file and put the extra code there. This does not produce any warnings.
The difference between 1 and 2 is that while the code formatting remains in the first alternatve (having to accept the 2 warnings) in the second all the code format is lost and its treated like normal text (but there is no warning)
I guess I would prefer the first. Of course, the only modification to the generated code file would be the #include statement.
The easiest solution would be to subclass NSArrayController, import the category and then use the subclass in IB. That way your bindings should automatically know of the category.
MoGenerator used to be good at generating custom classes without having to overwrite anything. I'm tinkering with updating it or something like it for Xcode 4.x since the original authors don't seem to have the time to do so.
After writing a few lesser programs when learning Java the way I've designed the programs is with Model-View-Control. With using MVC I have a plethora of getter methods in the model for the view to use.
It feels that while I gain on using MVC, for every new value added I have to add two new methods in the model which quickly get all cluttered with getter & setters.
So I was thinking, maybe I should use the notifyObserver method that takes an argument. But wouldn't feel very smart to send every value by itself either so I figured, maybe if I send a kind of container with all the values, preferably only those that actually changed.
What this would accomplish would be that instead of having a whole lot of getter methods I could just have one method in the model which put all relevant values in the container.
Then in the view I would have a method called from the update which extracted the values from the container and assigning them to the correct fields.
I have two questions concerning this.
First: is this actually a viable way to do this. Would you recommend me doing something along these lines?
Secondly: if I do use this plan and I don't want to keep sending fields that didn't actually change. How would I handle that without having to have if statements to check if the value is not null for every single value?
I've more familiar with the MVP paradigm, but hopefully they're similar enough to comment. While getters (and setters) in and of themselves are not necessarily evil, they are sometimes a sign that your subsystems are too strongly coupled. One really great way to decouple this is to use an event bus: see Best practices for architecting GWT apps. This allows the view to just shoot off events for the controller to listen for whenever something important happens, and the view can listen for events whenever something changes in the model that corresponds to updating the view. Ideally you wouldn't even need to ever pass the model to the view, if you can break up any changes into incremental pieces and just tell the view to change this part and then this other part.
If you feel you have too many getters (and setters) in your model class, maybe you have too many fields altogether. Is it possible that there are several distinct classes hiding within your model? If you extract these into separate classes, it may make your model more manageable.
OTOH the associated container you are thinking about could also be viable - but then why duplicate all data? You could instead use the associated container directly in the model to store all properties you can think of. And you can also pass this around for observers to get updates (preferably wrapped into an unmodifiable container, of course) - although in this setup you wouldn't need to.
In general, Java is a verbose language which expects you to put all those getters and setters (and a lot more) in place. However, any decent IDE can generate those for you with a few keypresses. Note also that you need to write them only once, and you will read and call them many many more times. Verbose also means easily readable.
If you have too many getter it's ok. But you shouldn't need the setter. The view is supposed to only read/query the model.
The MVC pattern should promote something that is asymmetric: the control update the model by calling methods in the model that embed the logic and update the sate accordingly; this respects encapsulation. The view reads/queries the model via the getters. This goes a bit against information hiding, but that's how MVC works.
I wouldn't personally pass all information in the events. It sounds complicated to me: either you end up with something that is not statically typed (e.g. you pass hashmaps), or with a plethora of typed events. I would stick with something simple, and have (possibly many) getter in the model.