SQL: I need help normalising - database-normalization

I need help in normalising the following table shown below. I keep getting repeated values when trying to assign a staff to a service.
The following are the tables after I normalised.
I split the staff column from the table. I also removed the serviceId and serviceName columns and made a new table called Services

Assuming all your SOMETHING_ID are PK
Services_Table contains:
ServiceId PK
ServiceName
Staff_Table contains:
StaffID PK
StaffName
Orders_Table:
OrderId PK
....
Order_Service could be :
OrderId (FK-Orders_Table)
ServiceID
Since Order and Service is One-to-Many relationship
Order_Staff could be:
OrderID (FK-Order_Table)
StaffID
Since Order staff is One-to-Many relation

Related

How to use Entity Framework 6 to update many-to-many relationship?

Someone else asked a similar question here: How can I use EF6 to update a many to many table
I mention that up front because I couldn't get any of the solutions given to work.
I also studied the solution give on Code Project: http://www.codeproject.com/Tips/893609/CRUD-Many-to-Many-Entity-Framework, but this doesn't work for me either.
I'm trying to keep this as simple as possible.
I have two tables: dbo.Teacher and dbo.Student. Each has an "ID" column that servers as a primary key. I also have a third table called dbo.StudentTeacher which has exactly two columns, both are non-nullable and foreign keyed to the previous two tables; in other words, it establishes a many-to-many relationship between teachers and students. As expected, the EDMX designed shows only dbo.Student and dbo.Teacher and infers the relationship between them.
Here is a script for the above; there is nothing else in the database.
CREATE TABLE dbo.Teacher
(
Id INT NOT NULL PRIMARY KEY,
Name VARCHAR(MAX)
);
CREATE TABLE dbo.Student
(
Id INT NOT NULL PRIMARY KEY,
Name VARCHAR(MAX)
);
CREATE TABLE dbo.TeacherStudent
(
TeacherId INT NOT NULL FOREIGN KEY REFERENCES Teacher(Id),
StudentId INT NOT NULL FOREIGN KEY REFERENCES Student(Id)
);
INSERT INTO Teacher(Id, Name)
VALUES
(101, 'Tom');
INSERT INTO Student(Id, Name)
VALUES
(201, 'Sue'),
(202, 'Stan');
INSERT INTO TeacherStudent(TeacherId, StudentId)
VALUES
(101, 201);
Now that I've established my data structures, I want to accomplish a very simple task. From the script above, you can see that we have one teacher named "Tom" who has a student named "Sue". We also have a student named "Stan" with no teacher. My task is to modify the database so that Sue is no longer Tom's student and Stan becomes Tom's student.
To accomplish this, I wrote the following code:
class Program
{
static void Main(string[] args)
{
using (var entities = new TestEntities())
{
// There is only one teacher in the system.
Teacher teacher = entities.Teachers.Single();
// This teacher has a student #201: Sue.
// I want to replace her with student #202: Stan.
teacher.Students.Clear();
teacher.Students.Add(new Student() { Id = 202 });
entities.SaveChanges();
}
}
}
It looks very simple: clear the students associated with Tom and then add Stan as Tom's student. However, when I run the code, I get the following error: Unable to update the EntitySet 'TeacherStudent' because it has a DefiningQuery and no <DeleteFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.
I tried simplifying the problem by trying to just remove Sue from being Tom's student without adding Stan, and I get the exact same error message.
As I understand, this error normally occurs when Entity Framework doesn't have enough information to do what you want it to do, but I really can't see what's missing. There are two simple tables with a join table between them and I need to be able to change which rows are related to which other rows.
I should also note that if I'm not mistaken, the change that I wish to make in this example should affect only the dbo.TeacherStudent table; the other two tables should not be touched.
Okay, after some more Google-Fu, I figured it out.
Even tho the join table must have only two columns with each column foreign keyed to the two tables to be related, the join table still needs a primary key, which can be a composite of the two foreign keys.
Thus, dbo.TeacherStudent should be created with this:
CREATE TABLE dbo.TeacherStudent
(
TeacherId INT NOT NULL FOREIGN KEY REFERENCES Teacher(Id),
StudentId INT NOT NULL FOREIGN KEY REFERENCES Student(Id),
PRIMARY KEY(TeacherId, StudentId)
);

How can I implement this schema using EF code-first? [Complex Composite Key combinations (multiple foreign tables)]

We have an existing database which we'd like to connect to using code-first EF.
An issue we have come across is in the following scenario...
**TABLE 1**
DebtorID Int PK (identity column)
Type Int PK FK ( value would be '1' - FK to Table 4)
**TABLE 2**
CreditorID Int PK (identity column)
Type Int PK FK (value would be '2' - FK to Table 4)
**TABLE 3**
TransactionID Int PK
ParentID Int FK
ParentType Int FK
-----------------------
**TABLE 4**
Type Int PK (identity column)
Description Varchar(max)
Table 3 has foreign key links to multiple tables (Table 1, Table 2, etc...). The key is unique by the type column. Constraints have been altered here to allow this scenario.
Q. How can we implement this schema using code-first? We have looked at Data Annotations, and also Fluent API, but can't come up with a solution other than to alter the database schema (which would be a big headache).
As it stands, we only seem to be able to link to a single foreign table.
The solution also has to account for other tables (not shown here) where the primary keys for Table 1 etc... are part of the primary key.
A real world view of our schema, and the issue with code-first.
Current schema:
http://oi60.tinypic.com/2aeug4m.jpg
Code-First schema:
http://oi62.tinypic.com/9schmc.jpg
I have found the answer using the Fluent Api - was much easier than I thought.
Simply in the OnModelCreating() method, I needed to add multiple ForeignKey entries to cover each link.
modelBuilder.Entity(Of TABLE_3).HasRequired(Function(p) p.TABLE_1).WithMany().HasForeignKey(Function(p) New With {p.ParentID, p.ParentType})
modelBuilder.Entity(Of TABLE_3).HasRequired(Function(p) p.TABLE_2).WithMany().HasForeignKey(Function(p) New With {p.ParentID, p.ParentType})
This was in addition to any configuration I did using Data Annotation with regards to setting up primary keys and navigational properties (e.g. navigation properties for TABLE_1 and TABLE_2)

Entity Framework - How to Insert to table with foreign keys without retrieving foreign table rows first

I'm having a hard time finding the exact answer to this question, so my apologies if this is redundant.
So I have 3 tables defined such that:
Person :PersonId, FirstName, LastName
Company: CompanyId, CompanyName
Order: OrderId, PersonId, CompanyId
On the Order table, there is a foreign key defined on the PersonId and CompanyId columns, thus, my Order entity class generated by EF has a navigation properties of type Person (not PersonId) and Company.
So, to insert into the Order table, I first need to query the person and company tables to get the person and company entities. Then I can construct the Order object using the Person and Company entities and save it to the db.
In my scenario, I am being passed a PersonId and CompanyId.
In classic SQL I would just do INSERT INTO Order Set (CompanyId, PersonId) - 1 database call. But with EF, I have to do 3 db calls. This seems like overkill.
Is there any way around this?
PS - I'm using EF 6. I know I could generate an expression and make it single call..but that would still yield two subselects.
You can just include foreign key properties in addition to the navigation properties and then set them using the ids you have. If you do this will not have to go to the database to get related entities for just a sake of setting the relationship.

Many-to-Many Relationships in EF4 with "Shared" columns

Disclaimer: Strictly speaking, what I have here is not a many-to-many relationship, but given that it's using an associative table, I figured it would be better to be slightly less accurate in order to give a better idea of what I'm doing.
I have the equivalent of the following three tables in my database:
Customer
---------
CustomerID PK
...
CustomerAddress
---------
CustomerID PK, FK -> Customer
AddressNo PK
... address columns ...
CustomerPrimaryAddress
--------------
CustomerID PK, FK -> Customer
AddressNo FK -> CustomerAddress (with CustomerID, so CustomerID
participates in both relationships)
If it's not obvious, the intent here is to allow for multiple addresses per customer, while designating at most one address per customer as "primary". I'm using an associative table to avoid placing a nullable PrimaryAddressNumber column on Customer, then creating a foreign key from Customer to CustomerAddress.
This is all well and good, but EF then places the CustomerPrimaryAddress entity in my model. Since its one and only purpose is to serve as an associative table, I have no need to represent this table in code. I removed the CustomerPrimaryAddress table from the conceptual model, then created an association between Customer and CustomerAddress like so:
Table Customer CustomerAddress
Multiplicity 1 0..1
I then mapped the association to use the CustomerPrimaryAddress table from the storage model, and all of the columns mapped just fine, or so I thought.
My issue is that now EF is complaining that CustomerID in CustomerPrimaryAddress is being mapped to two locations in my association, as it's mapped to both Customer and CustomerAddress.
Is there any way around this? I would prefer not to add a nullable column to Customer to represent the primary address number, as not only is this not a pleasant option from a DBA perspective, EF will also complain about having a cyclical relationship and I'll have to break inserts up in the code.
Thinking out loud here:
Customer
---------
CustomerID PK
...
CustomerAddress
---------
AddressNo PK
CustomerID FK -> Customer, non-nullable
... address columns ...
CustomerPrimaryAddress
--------------
CustomerID PK, FK -> Customer
AddressNo FK -> CustomerAddress
This seems like it should get the cardinalities right, but I may have missed something.

postgres ERROR: insert or update on table "xxxxx" violates foreign key contrain "xxxxx"

Hello
I have a main table BASECOMPANYDATA with BaseCompanyDataID as a PK. This is inhereted by
2 other tables CUSTOMERS & PRODUCTCOMPANIES. Now I have the table CONTACTS which I
want to connect with the 2 others as the customers and the productcompanies will have 0 or
more contacts. So I made a FK(BaseCompanyID) in CONTACTS and connected to the
BASECOMPANYDATA PK(BaseCompanyDataID). But when I am trying to insert a contact for
a record which exists in CUSTOMERS I get the following error:
ERROR: insert or update on table "xxxxx" violates foreign key contrain "xxxxx"
DETAIL: Key (BaseCompanyDataID)=(17) is not present in table "BaseCompanyData".
This ID exists in the above inherited table (BaseCompanyData).
Can someone explain why is this happening?
Thanks in advance
PS:Well, I have 4 tables:
1.BASECOMPANYDATA with BaseCompanyDataID as PK and some other fields.
2.CUSTOMERS which inherits from the above table so it has CustomerID as PK and has the fields of the BASECOMPANYDATA table namely BaseCompanyDataID etc.
3.PRODUCTCOMPANIES which inherits from BASECOMPANYDATA so it has the fields ProductCompanyID as PK and the fields of the inherited table like BaseCompanyDataID etc.
4.CONTACTS with ContactID as PK and BaseCompanyDataID as a FK. I tried to connect the table CONTACTS with 2 different ways. a. CONTACTS->BaseCompanyID with CUSTOMERS->BaseCompanyDataID and CONTACTS->BaseCompanyID with PRODUCTCOMPANIES->BaseCompanyDataID b. CONTACTS->BaseCompanyID with BASECOMPANYDATA->BaseCompanyDataID The result was the same error. Any answer on how I can create the FK using the inheritance, if there is. Thanks in advance
Did you read through the inheritance docs? Especially the 5.8.1. Caveats section?
http://www.postgresql.org/docs/9.0/static/ddl-inherit.html
...
Similarly, if we were to specify that cities.name REFERENCES some other table, this constraint would not automatically propagate to capitals. In this case you could work around it by manually adding the same REFERENCES constraint to capitals.
edit:
Inheritance is only half implemented in Postgsresql. If you want to save typing check out like in create table
In your first question I see the person recommended exactly the same thing I said. And now you have a problem? Hmm ...
This is pseudo sql I get from your repost:
base
baseid
customers(base)
baseid
id
products(base)
baseid
id
contacts
id
baseid references base(baseid)
Just do it the good old fashioned way!
base
id
customers
base_id references base(id)
id
products(base)
base_id references base(id)
id
contacts
id
base_id references base(id)