Document based core data app - add and remove additional attributes - swift

I have a document based core data app with entity "Languages". This entity has two permanent attributes "key" and "comments".
Is it possible programmatically add and remove additional attributes during runtime ("language_1", "language_2", etc.) ?
My goal is to avoid creating table with let say 50 attributes when user needs only few (I don't know upfront how many attributes will be necessary).
Or maybe I should choose other solution ? :)
EDIT
Case explanation:
When user creates new document, table "Languages" has only 2 attributes "key" and "comments". During working with the document user can any time add or remove language(s) - I mean attributes (columns) not rows in the table.
My goal is to have dynamic entity like below.

Yes, it's possible. But it's probably not what you want. You'd have to recreate the amended Managed Object Model, for each document, at runtime whenever the document is opened.
After seeing your sketch, I suggest a slightly different model. By the way, best style is to use singular nouns for Entities ("Section", not "Sections), plural nouns for to-many Relationships ("sections", not "relSection"), and omit the entity name in its attributes ("comment", not "sectionComment").
Use one Entity for your permanent attributes. Call it "Word". Word has attributes "comments" and "key", and to-many relationships "translations" and "sections". On the other end of the "translations" relationship is a Translation entity, which has attributes "text" and also perhaps the name of the language (either as a string or as another relationship).
Something like this:
For your first example, you'd have one instance of Word, 3 instances of Translation (.text = Home, Zuhause, and Casa), and 3 instances of Language (.name = English, German, Spanish). When you add the second line, you'll get 1 more instance of Word, 3 more instances of Translation, but 0 more Languages. Add the new Translation instances to the existing Language's "translations" relationship instead.

Related

Symfony2: Collection of dropdown select lists for a many-to-many relationship

The objective:
Having a many-to-many relation be displayed as a dynamic list of select inputs(single choice dropdown list)
User arrives on page with a single select field (multiple = false) populated with persisted entities and add/remove buttons. By clicking the add button, a new select field with the same options appears below the first, which adds a new entry in the M2M relation. By clicking remove the field disappears and the entry should be removed.
The model:
Two entities: User & Manager. A User has exactly one "special" Manager and unlimited normal Managers.
Managers manage unlimited users.To model this I have created two relationships for which the user is the "owner" (not sure how to translate this)
ManyToOne specialManager
ManyToMany normalManagers
I haven't created a many to many relationship with attribute "special" because the requirement is exactly one special manager and I wasn't sure if Symfony/Doctrine would cause problems down the line.
What I have:
I can display a multiple select field with the existing entities using Entity field type, as per the documentation. Functionally this is what I need, visually it is not.
I can also use the Collection field type to display a single text field, and add or remove more with JS, as per the documentation. Visually this is what I need, but The text fields (entity attribute) need to be replaced by choice field.
The question:
Before I continue digging, is there a simple way to achieve this list of select tags?
For anyone else who may eventually need a dynamic list of select fields:
I initially solved this issue by detaching the field(s) in event listeners, and handling the display/submission manually in the controller.
However I wasn't satisfied with this clunky solution and when I encountered the same need I used a second solution: creating an intermediary entity xxxChoice (in this case ManagerChoice) which is Mto1 inversed related to User and Mto1 related to Manager. Then by creating a ManagerChoiceType form with "Manager" entity field type I was able to easily display my collection of dropdown select lists.

How do I get the column name from an Entity Framework Association

I have an entity model built using the designer. In one of my tables (application), I have several foreign keys that reference the same status (status) table. As a result, when my associations were built, I have several entity objects built with an auto indexing name:
application_statuses2
application_statuses3
etc.
I'm building a "version history" type screen and want to be able to properly list the "friendly name" for each column modified. For example, I want to display "Destination Status" will be displayed instead of "application_statuses2". If I can determine the endpoint column name on the association in question, I can setup the proper display value.
I can find the entity object in the designer, I can even track where it references the foreign key in question that built the association, but I can seem to find the property that outlines the enpoints or column names. How do I determine the column name, or endpoint, on my association, or entity?
I wish it were more ready to hand, have been looking for it as well. Bit of a pain when you have multiple FKs to the same table.
Click on the navigation property you want to check
Under properties, look at the name of the association
At the top of properties, use the object navigator dropdown to switch to the association
Click into the 'Referential Constraint' property
Use the ellipses button on the right to bring up the column names
Dont know if there is a better way of doing this, but I certainly hope so!

Data modeling in CoreData, (folders and documents with many children, etc)

I have used CoreData a couple of times but data modeling was very simple. This time I am supposed to implement the following:
User can create documents and folders (they don't have to be real folders/directories).
Folders can contain documents or other folders
Documents have:
1 Title,
1 Description and
8 children
Each child also has a Title and a Description and could have 8 children
(optionally)
This could be as many levels (recursive) as the user desires.
I am not sure how to express this in CoreData. Could someone give a hand here?
Right now I think of:
"Child" entity with "Title" "Description" as attributes and "Children" as a relationship (one to many).
"File" entity with "IsFolder" as a boolean attribute and "Documents" as a relationship (one to many, pointing to "Child")
I am not sure if this well implements above structure in CoreData.
I am in the right path? Re-modeling data structure in CoreData could be painful (I've heard) so i would like to have a good structure from the beginning. I hope I can get some advice from you;)
Thanks in advance.
You probably want something like this (pseudocode):
Folder{
parent<<--(required,nullify)-->Folder.folders
folders<--(optional,cascade)-->>Folder.parent
documents<--(optional,cascade)-->>Document.folder
}
Document{
title:string
descriptionText:string
parent<<--(optional,nullify)-->Document.children
children<--(optional,cascade)-->>Document.parent
folder<<--(optional,nullify)-->Folder.document
}
(Word of warning: Don't ever use "description" as an attribute name. NSObject has a description method so every subclass of NSObject responds to the description message. It will cause all kinds of ugly problems if you have an attribute accessor of the same name.)

Entity Framework many-to-many question

Please help an EF n00b design his database.
I have several companies that produce several products, so there's a many-to-many relationship between companies and products. I have an intermediate table, Company_Product, that relates them.
Each company/product combination has a unique SKU. For example Acme widgets have SKU 123, but Omega widgets have SKU 456. I added the SKU as a field in the Company_Product intermediate table.
EF generated a model with a 1:* relationship between the company and Company_Product tables, and a 1:* relationship between the product and Company_Product tables. I really want a : relationship between company and product. But, most importantly, there's no way to access the SKU directly from the model.
Do I need to put the SKU in its own table and write a join, or is there a better way?
I just tested this in a new VS2010 project (EFv4) to be sure, and here's what I found:
When your associative table in the middle (Company_Product) has ONLY the 2 foreign keys to the other tables (CompanyID and ProductID), then adding all 3 tables to the designer ends up modeling the many to many relationship. It doesn't even generate a class for the Company_Product table. Each Company has a Products collection, and each Product has a Companies collection.
However, if your associative table (Company_Product) has other fields (such as SKU, it's own Primary Key, or other descriptive fields like dates, descriptions, etc), then the EF modeler will create a separate class, and it does what you've already seen.
Having the class in the middle with 1:* relationships out to Company and Product is not a bad thing, and you can still get the data you want with some easy queries.
// Get all products for Company with ID = 1
var q =
from compProd in context.Company_Product
where compProd.CompanyID == 1
select compProd.Product;
True, it's not as easy to just navigate the relationships of the model, when you already have your entity objects loaded, for instance, but that's what a data layer is for. Encapsulate the queries that get the data you want. If you really want to get rid of that middle Company_Product class, and have the many-to-many directly represented in the class model, then you'll have to strip down the Company_Product table to contain only the 2 foreign keys, and get rid of the SKU.
Actually, I shouldn't say you HAVE to do that...you might be able to do some edits in the designer and set it up this way anyway. I'll give it a try and report back.
UPDATE
Keeping the SKU in the Company_Product table (meaning my EF model had 3 classes, not 2; it created the Company_Payload class, with a 1:* to the other 2 tables), I tried to add an association directly between Company and Product. The steps I followed were:
Right click on the Company class in the designer
Add > Association
Set "End" on the left to be Company (it should be already)
Set "End" on the right to Product
Change both multiplicities to "* (Many)"
The navigation properties should be named "Products" and "Companies"
Hit OK.
Right Click on the association in the model > click "Table Mapping"
Under "Add a table or view" select "Company_Product"
Map Company -> ID (on left) to CompanyID (on right)
Map Product -> ID (on left) to ProductID (on right)
But, it doesn't work. It gives this error:
Error 3025: Problem in mapping fragments starting at line 175:Must specify mapping for all key properties (Company_Product.SKU) of table Company_Product.
So that particular association is invalid, because it uses Company_Product as the table, but doesn't map the SKU field to anything.
Also, while I was researching this, I came across this "Best Practice" tidbit from the book Entity Framework 4.0 Recipies (note that for an association table with extra fields, besides to 2 FKs, they refer to the extra fields as the "payload". In your case, SKU is the payload in Company_Product).
Best Practice
Unfortunately, a project
that starts out with several,
payload-free, many-to-many
relationships often ends up with
several, payload-rich, many-to-many
relationships. Refactoring a model,
especially late in the development
cycle, to accommodate payloads in the
many-to-many relationships can be
tedious. Not only are additional
entities introduced, but the queries
and navigation patterns through the
relationships change as well. Some
developers argue that every
many-to-many relationship should start
off with some payload, typically a
synthetic key, so the inevitable
addition of more payload has
significantly less impact on the
project.
So here's the best practice.
If you have a payload-free,
many-to-many relationship and you
think there is some chance that it may
change over time to include a payload,
start with an extra identity column in
the link table. When you import the
tables into your model, you will get
two one-to-many relationships, which
means the code you write and the model
you have will be ready for any number
of additional payload columns that
come along as the project matures. The
cost of an additional integer identity
column is usually a pretty small price
to pay to keep the model more
flexible.
(From Chapter 2. Entity Data Modeling Fundamentals, 2.4. Modeling a Many-to-Many Relationship with a Payload)
Sounds like good advice. Especially since you already have a payload (SKU).
I would just like to add the following to Samuel's answer:
If you want to directly query from one side of a many-to-many relationship (with payload) to the other, you can use the following code (using the same example):
Company c = context.Companies.First();
IQueryable<Product> products = c.Company_Products.Select(cp => cp.Product);
The products variable would then be all Product records associated with the Company c record. If you would like to include the SKU for each of the products, you could use an anonymous class like so:
var productsWithSKU = c.Company_Products.Select(cp => new {
ProductID = cp.Product.ID,
Name = cp.Product.Name,
Price = cp.Product.Price,
SKU = cp.SKU
});
foreach (var
You can encapsulate the first query in a read-only property for simplicity like so:
public partial class Company
{
public property IQueryable<Product> Products
{
get { return Company_Products.Select(cp => cp.Product); }
}
}
You can't do that with the query that includes the SKU because you can't return anonymous types. You would have to have a definite class, which would typically be done by either adding a non-mapped property to the Product class or creating another class that inherits from Product that would add an SKU property. If you use an inherited class though, you will not be able to make changes to it and have it managed by EF - it would only be useful for display purposes.
Cheers. :)

Naming them entities to make sense

I was noticing that the designer for the edmx is giving the entities and classes strange names, all in plural etc, what should be the correct naming for it?
like it is now is like:
Customers (entity)
CustomersSet (setname)
Cusomters (navigation property)
shall it be:
Customer (entity)
Customers (setname)
Customer (navigation property)
?
TIA
/M
If the designer is giving your entities plural names, that means that your database has plural table names. That's fine. Entity Framework version 4 will pluralize things automatically, but for now you need to fix this up yourself.
What I do is:
Entity type names are always singular
Entity set names are always plural
Navigation property names are either singular or plural, depending upon the cardinality of the relationship. So a one to one property would be singular, and a one to many property would be plural.
I would tend to agree on the two first present in the list. the last one may be a set or a single entity.
Customer (entity) Customers (setname) Customer (navigation property)