Is it possible/or good practice to have one table like an address book that is related to different entities e.g: People, Companies, etc
I am thinking of using a compsite FK (typeid = entity type id e.g: 1 for people, 2 for companies etc, while the other column refers to the pk of the entity's table).
The other alternative I have is to use a junction table between the entities and address book table.
I am using VS 2005 C#, and sql server 2008
Assumption: your entities are all stored in one table with a type discriminator
Yes, a foreign key can have multiple columns.
An address entry only needs to know the PK of the parent entity
It does not need to know the type of entity: entityType is an attribute of entity not address
Junction table or straight FK? It depends on your relationships:
Can one address be shared by more than one entity?
Can one entity have more then one address?
Yes to both: junction table
Yes to Q1 only: address PK is an attribute of entity. Entity is the child table in the FK
Yes to Q2 only: entity PK is an attribute of address. Address is the child table in the FK
And the case I would not expect:
No to both: 1:1 relationship or you need only one table, address is an attribute of entity
I see no need for a type and an entity_id that refers to one table or the other. This is a complicated approach (two tables using the same ID pool and no foreign key to a table possible) that might cause problems later.
Your problem seems so simple that no tricks should be needed here.
You have companies, persons and addresses. If each person and each company has one address, you have the address id in the companies and persons tables. If a person can have more than one address you need a bridge table. Same for more than one address per company. That's all.
Related
Recently I'm working on a project, in which I need save multiples subjects in my database, and numbers of subject will be change as per student's class. e.g: class "VII" has 6 subject (included 1 option subject), class "VIII" has 8 subjects (1 included option subject) and so on. Even the option subject can be different according to student's choice.
I'm using CheckedListBox control. Here is a screenshot.
I'm using MS Sql Server 2012. I'm facing difficulty to design database table. I can't understand should i create all the subject columns in my student table or ????(best way). Please help me, thanks in advance.
What you are describing is something that is called a Many to Many relationship. Many Classes have Many students.
You will have a students table, a subjects table and then a table student_subject table which links both the primary keys of the students and subjects table.
Reference: Many to Many
If a Student can have multiple Subjects, and a Subject can have multiple Students, then that's a many-to-many relationship. Which means there would need to be an intermediary table to link them.
Start with the tables for the objects themselves:
Student
----------
ID
Name
etc.
and
Subject
----------
ID
Name
etc.
Since these are independent aggregate root objects in the domain and neither one owns another one, their tables just contain information which describes that object. A Subject, for example, could have a name and a description, maybe a list of pre-requisites, etc.
Then you create the relationship table between them. A common practice is to just combine the names:
StudentSubject
----------
StudentID
SubjectID
If no two pairs of Student and Subject can be repeated, then the two foreign keys together can make the primary key. If they can be repeated (if the same Student can have the same Subject more than once) then you'd probably want to add a separate primary key to the table.
At its simplest, all this table does is create the relationships between the records in the main tables. However, this can potentially grow to be a domain entity in and of itself. If there are any attributes which describe the relationship between a Student and a Subject, those would be added to this table.
Your database schema should look something like this......
Students
Student_ID (PK)
Student_Name
etc .......
Subject
Subject_ID (PK)
Fee
etc......
Student_Subjects
Student_ID FK Students(Student_ID)
Subject_ID FK Subject(Subject_ID)
DateStarted
etc.....
I've been used to this kind of convention before starting to work with Entity Framework/MVC:
tblMyItem (id, id_lookup1, val2, val3, val4...) - single, generic table
tblkLookup1 (id, val1, val2,...) - one to many relation table
tblmMyItemLookup2 (id, id_myitem, id_lookup2) - many to many relations table.
Recently I've found somewhere on the web that it's not good to create id column in tblmMyItemLookup2 when using Entity Framework, but I couldn't find more information on that. Could anyone please explain, why this is so significant?
When designing many-2-many relationship(i.e Student - Teacher) based on intermediate table (Student2Teacher) with only 2 foreign key columns, you'll end up having entities with navigation properties without intermediate table(no entity will be created for that table in context at all):
Student.Teachers <- EntityCollection<Teacher>
Teacher.Students <- EntityCollection<Student>
Meanwhile, if you add any extra field to your intermediate table, you'll have navigation properties pointing to intermediate entity:
Student.Student2Teacher
Teacher.Student2Teacher
making your querying uselessly more complex
In general we use lookup tables to macth associated records in two different tables that have a many to many relationship. For instance, let we have three tables: Students, Professors and StudentsProfessors. Since, a student can atten lesson that are serviced by many professors and a professor can teach more than one leasons then this is clearly a many to many relationship. So the lookup table called StudentsProfessors is used to match a student to her/his professors and vice versa. Now, the use of an id for each record of this lookup table is meaningless. We are not going to use this number anywhere. We just need to know that Student with studentId=10 is associated with professors with ids in (1,2,4,9). Just that and not the id of this record in the lookup table.
I have the following tables:
Table Group (
id INT PK,
year INT PK,
name VARCHAR
)
Table Person (
id PK,
GroupID INT,
name VARCHAR
)
The database does not have foreign keys defined so I want to create a manual association from the Person tables GroupID to the Group tables id.
To do this I right click Person and Add an association. I create a Many to One association and everything works. The problem is when I go to add the mapping. Because the Group table has two primary keys entity framework was something from the Person table to map to the year key.
What do I need to do to create the association?
You cannot create such association because EF follows same rules as database. All PK columns from principal entity must exists as FK columns in dependent entity.
The only way can be some database view selecting distinct Groups with Id and Name and mapped as read only entity and build navigation between those two. I didn't try it but I guess it should work. It will have its own disadvantages because you will have two completely unrelated entities for group and the entity related to person will not accept any modification (without mapping custom SQL commands or stored procedures to insert, updated and delete operations).
I have Products table and Customers table. Thus there is many to many relationship between them. This is my code to create that relationship using ModelBuilder:
modelBuilder.Entity<Customer>().
HasMany(c => c.ProductsPurchased).
WithMany(p => p.Customers).Map(m =>
m.MapLeftKey("CustomerId").
MapRightKey("ProductId").
ToTable("CustomersXProducts"));
Problem here is the Join table contains primary key of CustomerId and ProductId. This essentially means one customer can purchase the same product only one time. How can I resolve this issue? I don't want CustomerId to be a primary key in my join table.
You cannot resolve the issue with your database. You generally need some additional unique column to be primary key of your junction table or you need some addition data column to form composite key with both CustomerId and ProductId. That will lead to change in your model. You will need to expose junction table as an entity - Customer and Product entities must be related to the new entity.
Perhaps you will need this anyway. It is not very common to have such relation without any additional data. Perhaps your model needs bigger change. For example customer tracking system usually uses some form of entities like Customer, Order, OrderItem, Product so there is no relation between Customer and Product directly.
I have several tables in my SQL2008 DB, Managers(ManagerID is a PK, incremental) and Customers(CustomerID is a PK, incremental) are among them. All ID columns are int. They are connected with junction table ManagersCustomers(fields: CustomerID is a PK, ManagerID) and there are relations: from CustomerID in Customers to same in junction table with delete cascade rule and from ManagerID in Managers to same in junction table with delete cascade too. So I have Managers 0..1 to * Customers relation in my edmx model after generating it from my DB and I can see this relation is mapped to junction table. I tested junction table in SQL Server Management Studio, it works correctly. Ok.
In my app I have 2 parts - edmx model on server side connected with client side through WCF Data Service. In client part I'm creating instance of my entities class, and in debug mode I can watch entities class instance's data. Both entities Customers and Managers are filled with data correctly, but in navigation fields I can see only 0. For example I have Customer with CustomerID = 1 connected with Manager with ManagerID=3 and there is a record in junction table. So, if it would work correctly, I would see my manager in navigation field of Customers entity and same with customer nav field in Managers entity. But I can see only zeros.
The easiest thing to do is to change the ManagersCustomers table so that both columns are part of the PK, and then recreate your model. The GUI designer won't pick it up as a many-to-many association unless you do.