SQL value contrains to another table data - c#

I have a couple of tables, lets say I have a cars table and I have another table which hold all types of cars available(just to avoid multiple entries on the cars table) so I want a constraint on my cars table that has a "list/set" of types of cars FROM the TypesOFCar Table this table contains (Make, Model, etc..) how can I archive this.
I want it modular so I can just add another kind of car to the TypeOfCar table and it becomes available on the Cars table, thx in advance.

The best way to implement this would be through a foreign key constraint. Essentially, you derive your tables such like:
CREATE TABLE dbo.CarType
(
[Id] INT NOT NULL DEFAULT(1, 1),
[Description] VARCHAR(255) NOT NULL
CONSTRAINT PK_CarType PRIMARY KEY NONCLUSTERED ([Id])
)
CREATE TABLE dbo.Car
(
[Id] INT NOT NULL DEFAULT(1, 1),
[Registration] VARCHAR(7) NOT NULL,
[CarType_Id] INT NOT NULL
CONSTRAINT PK_Car PRIMARY KEY NONCLUSTERED ([Id]),
CONSTRAINT FK_Car_CarType_Id FOREIGN KEY ([CarType_Id]) REFERENCES dbo.CarType ([Id])
)
In those example tables, I create a foreign key constraint that maps the CarType_Id column of the Car table to the Id column of the CarType. This relationship enforces that a CarType item must exist for the value being specified in the Car table.

You want to add a CarType column to your Cars table and make it a foreign key to your TypeOfCar table.

Related

Asp.Net Core Entity Framework Migration Error: index needed in a foreign key constraint [duplicate]

I need to ALTER my existing database to add a column. Consequently I also want to update the UNIQUE field to encompass that new column. I'm trying to remove the current index but keep getting the error MySQL Cannot drop index needed in a foreign key constraint
CREATE TABLE mytable_a (
ID TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;
CREATE TABLE mytable_b (
ID TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;
CREATE TABLE mytable_c (
ID TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;
CREATE TABLE `mytable` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`AID` tinyint(5) NOT NULL,
`BID` tinyint(5) NOT NULL,
`CID` tinyint(5) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `AID` (`AID`,`BID`,`CID`),
KEY `BID` (`BID`),
KEY `CID` (`CID`),
CONSTRAINT `mytable_ibfk_1` FOREIGN KEY (`AID`) REFERENCES `mytable_a` (`ID`) ON DELETE CASCADE,
CONSTRAINT `mytable_ibfk_2` FOREIGN KEY (`BID`) REFERENCES `mytable_b` (`ID`) ON DELETE CASCADE,
CONSTRAINT `mytable_ibfk_3` FOREIGN KEY (`CID`) REFERENCES `mytable_c` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB;
mysql> ALTER TABLE mytable DROP INDEX AID;
ERROR 1553 (HY000): Cannot drop index 'AID': needed in a foreign key constraint
You have to drop the foreign key. Foreign keys in MySQL automatically create an index on the table (There was a SO Question on the topic).
ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_1 ;
Step 1
List foreign key ( NOTE that its different from index name )
SHOW CREATE TABLE <Table Name>
The result will show you the foreign key name.
Format:
CONSTRAINT `FOREIGN_KEY_NAME` FOREIGN KEY (`FOREIGN_KEY_COLUMN`) REFERENCES `FOREIGN_KEY_TABLE` (`id`),
Step 2
Drop (Foreign/primary/key) Key
ALTER TABLE <Table Name> DROP FOREIGN KEY <Foreign key name>
Step 3
Drop the index.
If you mean that you can do this:
CREATE TABLE mytable_d (
ID TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;
ALTER TABLE mytable
ADD COLUMN DID tinyint(5) NOT NULL,
ADD CONSTRAINT mytable_ibfk_4
FOREIGN KEY (DID)
REFERENCES mytable_d (ID) ON DELETE CASCADE;
> OK.
But then:
ALTER TABLE mytable
DROP KEY AID ;
gives error.
You can drop the index and create a new one in one ALTER TABLE statement:
ALTER TABLE mytable
DROP KEY AID ,
ADD UNIQUE KEY AID (AID, BID, CID, DID);
A foreign key always requires an index. Without an index enforcing the constraint would require a full table scan on the referenced table for every inserted or updated key in the referencing table. And that would have an unacceptable performance impact.
This has the following 2 consequences:
When creating a foreign key, the database checks if an index exists. If not an index will be created. By default, it will have the same name as the constraint.
When there is only one index that can be used for the foreign key, it can't be dropped. If you really wan't to drop it, you either have to drop the foreign key constraint or to create another index for it first.
Because you have to have an index on a foreign key field you can just create a simple index on the field 'AID'
CREATE INDEX aid_index ON mytable (AID);
and only then drop the unique index 'AID'
ALTER TABLE mytable DROP INDEX AID;
I think this is easy way to drop the index.
set FOREIGN_KEY_CHECKS=0; //disable checks
ALTER TABLE mytable DROP INDEX AID;
set FOREIGN_KEY_CHECKS=1; //enable checks
drop the index and the foreign_key in the same query like below
ALTER TABLE `your_table_name` DROP FOREIGN KEY `your_index`;
ALTER TABLE `your_table_name` DROP COLUMN `your_foreign_key_id`;
Dropping FK is tedious and risky. Simply create the new index with new columns and new index name, such as AID2. After the new Unique Index is created, you can drop the old one with no issue. Or you can use the solution given above to incorporate the "drop index, add unique index" in the same alter table command. Both solutions will work
In my case I dropped the foreign key and I still could not drop the index. That was because there was yet another table that had a foreign key to this table on the same fields. After I dropped the foreign key on the other table I could drop the indexes on this table.
If you are using PhpMyAdmin sometimes it don't show the foreign key to delete.
The error code gives us the name of the foreign key and the table where it was defined, so the code is:
ALTER TABLE your_table DROP FOREIGN KEY foreign_key_name;
You can show Relation view in phpMyAdmin and first delete foreign key. After this you can remove index.
You can easily check it with DBeaver. Example:
As you can see there are 3 FKs but only 2 FK indexes. There is no index for FK_benefCompanyNumber_beneficiaries_benefId as UK index provide uniqueness for that FK.
To drop that UK you need to:
DROP FK_benefCompanyNumber_beneficiaries_benefId
DROP UK
CREATE FK_benefCompanyNumber_beneficiaries_benefId
The current most upvoted answer is not complete.
One needs to remove all the foreign keys whose "source" column is also present in the UNIQUE KEY declaration.
So in this case, it is not enough to remove mytable_ibfk_1 for the error to go away, mytable_ibfk_2 and mytable_ibfk_3 must be deleted as well.
This is the complete answer:
ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_1;
ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_2;
ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_3;
Its late now but I found a solution which might help somebody in future.
Just go to table's structure and drop foreign key from foreign keys list. Now you will be able to delete that column.

Entity Framework - Composite Primary key, two foreign keys, DB First not generating model

I have been trying to handle translations in my database and also Entity Framework. I am generating the following tables but the translate model is not being generated by Entity Framework. I have tried numerous combinations but it won't generate. But, for some reason there is one LanguageTranslate model that IS being generated I think it's because there is just a regular primary key and only one foreign key.
Any ideas are very welcome? Thank you.
CREATE TABLE [dbo].[Merchant]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY
-- Other columns here
)
CREATE TABLE [dbo].[MerchantTranslate]
(
[MerchantId] INT NOT NULL,
[LanguageId] INT NOT NULL,
[Name] NCHAR(50) NOT NULL,
CONSTRAINT [PK_MerchantTranslate]
PRIMARY KEY ([MerchantId], [LanguageId]),
CONSTRAINT [FK_MerchantTranslate_ToMerchant]
FOREIGN KEY ([MerchantId]) REFERENCES [Merchant]([Id]),
CONSTRAINT [FK_MerchantTranslate_ToLanguage]
FOREIGN KEY ([LanguageId]) REFERENCES [Language]([Id])
)

How do I create Entity Framework Model First Association Table?

I need to write a DB script which creates an association table in my database, creating a parent-child structure within a single table. The resulting model should be something like this:
with n to n relation between the articles.
First of all, let's look at the table creation itself. For the association to work properly in EF, it's essential that primary keys are properly declared. If we don't declare PK for the association table, while the model designer will interpret the association correctly, any attempt to insert into the table will throw error on .SaveChanges().
To create the model specified in the model, we're going to use following code:
create table Article (
articleID int not null identity(1,1),
description varchar(500) not null
)
alter table Article add constraint PK_ArticleID
primary key (articleID)
create table ArticleAssociation (
associatedArticle1ID int not null,
associatedArticle2ID int not null
)
alter table ArticleAssociation add constraint PK_ArticleAssociationID
primary key clustered (associatedArticle1ID, associatedArticle2ID ASC)
alter table ArticleAssociation add constraint FK_AsscociatedArticle1ID
foreign key (associatedArticle1ID) references Article (articleID)
alter table ArticleAssociation add constraint FK_AsscociatedArticle2ID
foreign key (associatedArticle2ID) references Article (articleID)
Now that the structure exists in DB, we can import both Article table and the ArticleAssociation table into our .edmx model. When the import is complete, the tables in model will look like this:
Note the absence of ArticleAssociation table itself, and its generation as an 'Association' type. We may now access the associated objects traditionally via navigation properties:
using (EFTestingEntities efso = new EFTestingEntities())
{
Article article1 = new Article();
article1.description = "hello";
Article article2 = new Article();
article2.description = "world";
efso.Article.Add(article1);
efso.Article.Add(article2);
article1.Article2.Add(article2);
article2.Article1.Add(article1);
efso.SaveChanges();
}

Add a field to a relation table and access row values through code

Using EF code first and Fluent, I've created two tables containing data and a third table which is the "relation table" (not sure what the 'official' word for it is?). Each row holds Id's from both tables and defines a many-to-many relation between the two.
The tables hold purchase orders and products. Now I need to specify the amount of products in a purchase order as well, so my most logical conclusion was to add a field in the relation table that specifies the quantity, so that the table will become:
orderId | productId | quantity
83923 | 867392 | 100
83923 | 865392 | 250
83923 | 323392 | 50
Is this possible using EF code first? I couldn't find a way, but it's hard to search for a solution since I find it hard to concisely describe what I need to do.
I thought I could add a field using the designer, which works, but I have no idea how to access the value through code now.
My tables:
The field/table names are all in Dutch, but hopefully it's understandable & readable.
-- Purchase orders
CREATE TABLE [dbo].[InkoopOrders] (
[InkoopOrderId] INT IDENTITY (1, 1) NOT NULL,
[Kenmerk] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_dbo.InkoopOrders] PRIMARY KEY CLUSTERED ([InkoopOrderId] ASC)
);
-- Products
CREATE TABLE [dbo].[Artikelen] (
[ArtikelId] INT IDENTITY (1, 1) NOT NULL,
[Kenmerk] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_dbo.Artikelen] PRIMARY KEY CLUSTERED ([ArtikelId] ASC)
);
-- Relation table
CREATE TABLE [dbo].[InkoopOrderArtikel] (
[InkoopOrderId] INT NOT NULL,
[ArtikelId] INT NOT NULL,
CONSTRAINT [PK_dbo.InkoopOrderArtikel] PRIMARY KEY CLUSTERED ([InkoopOrderId] ASC, [ArtikelId] ASC),
CONSTRAINT [FK_dbo.InkoopOrderArtikel_dbo.InkoopOrders_InkoopOrderId] FOREIGN KEY ([InkoopOrderId]) REFERENCES [dbo].[InkoopOrders] ([InkoopOrderId]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.InkoopOrderArtikel_dbo.Artikelen_ArtikelId] FOREIGN KEY ([ArtikelId]) REFERENCES [dbo].[Artikelen] ([ArtikelId]) ON DELETE CASCADE
);
This was achieved through creating the two models, and defining the relation in Fluent:
modelBuilder.Entity<InkoopOrder>()
.HasMany(o => o.Artikelen)
.WithMany(a => a.InkoopOrders)
.Map(
m => {
m.MapLeftKey("InkoopOrderId");
m.MapRightKey("ArtikelId");
m.ToTable("InkoopOrderArtikel");
}
);
In EF, in may to many relationships, the association table can only have the Key columns of the related tables. So, no, you cannot do that with a many to many using EF. If you wanted to do this, you'd need to specify two one-to-may relationships (from both many to many tables, to the association table). Look at this SO answer for a full explanation.
However, I don't understand why you want to use a many to many. You simply need to use the classical Order table with a child OrderDetail table that has the ProductId, UnitPrice, Units, Total, and so on. Forget about using the many to many for this case. It's much easier in this way.

Exist foreign key depend 2 primary key?

As question title. Example: i have 3 table employee,teacher,student.
one employee's FOREIGN KEY depend student's PRIMARY KEY
one employee's FOREIGN KEY depend teacher's PRIMARY KEY
I tried but i couldn't.
As I understand your question:
Can 1 Foreign Key refer to 2 different tables?
Answer: No, it cannot.
You can (and probably should) easily define 2 separate foreign keys:
Employee IS|HAS Student
Employee IS|HAS Teacher
You cant have a foreign key linking to two tables.
if you have control over the table structure it might make more sense to have a different structure
table: Person
table: EmployeeInfo (all information about being an employee i.e. EmpNo, ClockNo etc) with a foreign key on Person
table: TeacherInfo (all information about being a teacher i.e. HomeRoom, subject etc) with a foreign key on Person
table: StudentInfo (all information about a student i.e. course, funding type etc) with a foreign key on Person
that way with some simple joins you can get all teachers that are employees, or all students that are employees, or all employees that are neither teachers nor students
One way to do this would be to create a people table that is the parent table and then child tables students, teachers and employees which would have foreign keys from their primary key to the people table. eg:
CREATE TABLE people
(
id bigserial NOT NULL,
first_name character varying(128) NOT NULL,
last_name character varying(128) NOT NULL,
-- other columns appropriate to a person
CONSTRAINT people_pk PRIMARY KEY (id)
)
CREATE TABLE students
(
fk_person bigint NOT NULL,
-- other columns appropriate to the student
CONSTRAINT students_pk PRIMARY KEY (fk_person),
CONSTRAINT students_fk FOREIGN KEY (fk_person)
REFERENCES people (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE teachers
(
fk_person bigint NOT NULL,
-- other columns appropriate to the teacher
CONSTRAINT teachers_pk PRIMARY KEY (fk_person),
CONSTRAINT teachers_fk FOREIGN KEY (fk_person)
REFERENCES people (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE employees
(
fk_person bigint NOT NULL,
-- other columns appropriate to the employee
CONSTRAINT employees_pk PRIMARY KEY (fk_person),
CONSTRAINT employees_fk FOREIGN KEY (fk_person)
REFERENCES people (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
You could also add a discriminator column to people to allow you to distinguish between students and teachers and a check (or trigger) on the discriminator column in employees to ensure that only teachers and students are put in that table. For more on discriminator columns take a look at the hibernate documents

Categories