I am using EF 4.1 RC and CodeFirst/POCO to build my database by code.
Imagine having a many-to-many relationship like Teachers-Students (one teacher can have many students, and one student may have many teachers). Accordingly I have two POCOs: (1) Teacher and (2) Student.
When EF creates the corresponding tables you will end up with three tables: (1)Teachers, (2) Students and (3) an extra join table. The join table contains exactly two fields: a Teacher_ID and a Student_ID.
I was wondering if I had any chance to add an extra field to the join table, e.g. "Grade" (the grade a certain teacher gives a certain teacher)?
Currently I have no idea how to achieve this with only two POCOs.
So I guess all I can do is create a third POCO (for the join table) manually, am I right? That will certainly work, but then I am losing nice navigation properties like oneTeacher.Students.First(), etc. That is the main reason why I am still looking for another way.
That's correct, and does not only apply to Code-first. If you have extra fields in your joining table, you will have it mapped as an entity. And vice-versa, if you want an extra field in your joining table, you need to create a new entity and have zero-or-one-to many or one-to-many navigation properties to the Teacher and Student entities. In any case, you lose the comfort of accessing Teacher.Students and Student.Teachers and have to go via the intermediate entity.
Alternatively, you could think about modeling the DB structure differently and extracting the extra info into the Teacher or Student or a fourth entity. But that depends entirely on your scenario.
Yes, the join table cannot have a payload or you need to break it down to 2 one to many association which will result in creating a third entity to hold the PKs as well as the additional properties.
This is an idea I still haven't found time to try it out. Maybe you can keep your Student and Teacher classes as they are, and add a third POCO StudentGrade with properties Student, Teacher and Grade. Then you'll have to use the fluent API to make sure that both the many to many relation between Student and Teacher and the StudentGrade class map to the same table.
Hope that helps
Related
Can someone check my ERD, because I don't know whether I'm doing it correctly or not. I'm not sure about the difference between strong and weak entity, what I'm sure is that strong entity has their own primary key.
Other than that, is it correct i need to take Payment_ID as foreign key in my order table ? and what other attribute that i could have in my ORDER TABLE
Maybe some suggestion on what to add or improve on my ERD. Here i have a image for my ERD. Thank You
Entity Relationship Diagram
PAYMENT has an ORDER_ID and ORDER has a PAYMENT_ID. Having both fields is redundant, I would remove ORDER.PAYMENT_ID which would be a nullable field if customers don't pay immediately.
ORDER_DETAILS requires a PK, either a surrogate key ORDER_DETAIL_ID or the combination of ORDER_ID, ITEM_ID.
Can a PAYMENT use only one or more than one COUPON? The cardinality on the crow's foot line says more than one, but the PAYMENT.COUPON_ID field would allow only one. A nullable PAYMENT_ID in the COUPON table would be a better choice.
You have some doubtful minimum cardinalities. A CUSTOMER must place at least one ORDER? Ok, I can accept that. An EMPLOYEE must take at least one ORDER? So everyone in the company must take orders, and you're not going to record employees until they've taken an order? Also, every ITEM must be referenced in ORDER_DETAILS? Are you not going to want to record items on offer before they're ordered?
Finally, a note on terminology: your diagram is better called a table diagram, not an ERD. To be called an entity-relationship diagram, a diagram has to distinguish the concepts of the entity-relationship model. The style of diagram you used doesn't distinguish entity sets (i.e. ID fields) from value sets (non-ID fields) or entity relations (tables with single-field PK) from relationship relations (tables with composite PK, i.e. ORDER_DETAILS is a relationship relation).
I have entities "Article" and "Product". Now I want to add comments to these 2 entities. Should I create 2 different entities "ArticleComment" and "ProductComment" with the same properties, and build a ManyToOne relation to their respective entity, or create a single "Comment" entity and find a way to build a relation to both "Article" and "Product" entities. Considering solution #2, how could I do that ?
Considering solution #2, how could I do that ?
One way would be to use Single Table Inheritance
Single Table Inheritance is an inheritance mapping strategy where all classes of a hierarchy are mapped to a single database table. In order to distinguish which row represents which type in the hierarchy a so-called discriminator column is used.
This means that you can easily create two separate entities ArticleComment and ProductComment both extending Comment. Then you use the advantages DiscriminatorMap column provides.
Your Comment entity could hold a relation called parent for instance that would refer to either your Article or Product entities. By creating new instance of ArticleComment or ProductComment your discriminator map field would be automatically populated depending on which type you're using.
This would also give you advantages with using DQL to query related comments by their type. Example from documentation:
$query = $em->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee');
And more. You can read that chapter here. Of course this is just a sample and you can use completely different approach.
I have table (let's name it "First") with columns id, userID, moonID, typeID. And another table (let's name it "Second") where is also column "typeID" and TypeName (simple example, basicly this table is a huge storage of data).
I need create simple relations with this two (entities) tables such way that i can simple create new entries in "First" table and remove\edit them. But i don't want to del\add\edit entries from "Second" table. So "Second" is untouchable at all, we just select data from "Second" by typeID of "First". How can i do this?
I want to see two entities and controller. Please help me with it.
Its very easy have a look at here
http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html
You will know what to do. they have examples over there.
By default Doctrine wont delete the linked side unless you do onCascade="Delete"
You can use OnDelete= Null if you want to make the linked is to null in case of deletetion of owning side
Using Docrine2 entities, I have a "list" entity, with a manytomany relationship with "item".
I need to manipulate and save the order of the items in the list. I can't figure out how to accomplish this using Doctrine2. What I want is a joiner table that looks something like:
list_item
=========
list_id
item_id
sort_order
All I can find is this outdated to-do item: http://www.doctrine-project.org/jira/browse/DDC-213
Can I accomplish this using Doctrine? Or is there some other way I should be going about this?
Thanks.
Here is an exerpt from this docs section, that answers your question:
Real many-to-many associations are less common. [...] Why are many-to-many associations less common? Because frequently you want to associate additional attributes with an association, in which case you introduce an association class. Consequently, the direct many-to-many association disappears and is replaced by one-to-many/many-to-one associations between the 3 participating classes.
i'm having a little problem in my project. i'm using ADO.Net Entity Data Model,
let's say i have 2 Tables:
Offices : a. id
b. Name
Requests: a. rid
b.fname
c.lname
d.mobile
i want the requests table will have a relations to the offices table that each row in requests will have the id of the one of the tables.
i tried to do 1 to many relations but it didn't work , i just couldnt add data to the table.
thanks for your guidence
Your Requests table needs to have a field to relate back to the offices table. Which typically should be named OfficeID or something similar. Add that field and create the relationship from Offices.ID to Requests.OfficeID and it will work fine.