The ALTER TABLE statement conflicted with the FOREIGN KEY constraint - sql-server

When I run the following migration, I am getting the following error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
I have an existing database and refactoring the model to include a navigation property.
See the original model and then the new model:
Original model:
public class Student
{
public int ID { get; set; }
public string Name { get; set; }
public string Country { get; set; }
}
New model:
public class Student
{
public int ID { get; set; }
public string Name { get; set; }
public int CountryID { get; set; }
public virtual Country Country { get; set; }
}
public class Country
{
public int ID { get; set; }
public string Country { get; set; }
}
Add-Migration navigation property:
public override void Up()
{
CreateTable(
"dbo.Countries",
c => new
{
ID = c.Int(nullable: false, identity: true),
CountryName = c.String(),
})
.PrimaryKey(t => t.ID);
AddColumn("dbo.Students", "CountryID", c => c.Int(nullable: false));
CreateIndex("dbo.Students", "CountryID");
AddForeignKey("dbo.Students", "CountryID", "dbo.Countries", "ID", cascadeDelete: true);
DropColumn("dbo.Students", "Country");
}
Update-Database error:
System.Data.SqlClient.SqlException (0x80131904): The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_dbo.Students_dbo.Countries_CountryID". The conflict occurred in database "aspnet-navprop-20141009041805", table "dbo.Countries", column 'ID'.

I got same problem, my table had data therefore I changed foreign key column to nullable.
AddColumn("dbo.Students", "CountryID", c => c.Int(nullable: true));
You should change your code like that then run again Update-Database -Verbose
public override void Up()
{
CreateTable(
"dbo.Countries",
c => new
{
ID = c.Int(nullable: false, identity: true),
CountryName = c.String(),
})
.PrimaryKey(t => t.ID);
AddColumn("dbo.Students", "CountryID", c => c.Int(nullable: true));
CreateIndex("dbo.Students", "CountryID");
AddForeignKey("dbo.Students", "CountryID", "dbo.Countries", "ID", cascadeDelete: true);
DropColumn("dbo.Students", "Country");
}

I had this same issue and truncated the table with the foreign key records and it succeeded.

If there is a data in the table (Student table) delete them and then re-try again.

Against your Student entity you can mark your CountryId property as nullable using a question mark appended to the type, i.e.
public class Student
{
public int ID { get; set; }
public string Name { get; set; }
public int? CountryID { get; set; }
public virtual Country Country { get; set; }
}

Related

How can I solve on delete no action or on update no action problen when using code-first in Entity Framework with authentication

I'm creating a project for hospital automation in user authentication and using code-first in Entity Framework.
Here my Hospital entity:
public int Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
Here my Clinic entity:
public int Id { get; set; }
public string Name { get; set; }
And my HospitalAndClinic entity:
public int Id { get; set; }
public int HospitalId { get; set; }
public int ClinicId { get; set; }
[ForeignKey("HospitalId")]
public Hospital Hospital { get; set; }
[ForeignKey("ClinicId")]
public Clinic Clinic { get; set; }
This is the Doctor entity:
public string Branch { get; set; }
public int? HospitalAndClinicId { get; set; }
[ForeignKey("HospitalAndClinicId")]
public HospitalAndClinic HospitalAndClinic { get; set; }
This is my employee entity
public string Position { get; set; }
public int HospitalAndClinicId { get; set; }
[ForeignKey("HospitalAndClinicId")]
public HospitalAndClinic HospitalAndClinic { get; set; }
My Doctorand 'Employee' tables extend from Person class that has fields like id, name etc.
When I do migration I get this problem
Introducing FOREIGN KEY constraint 'FK_Doctor_HospitalAndClinic_HospitalAndClinicId' on table 'Doctor' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
How can I solve this?
In the migration, under constrains you can add onDelete property to say what happens when deleted.
migrationBuilder.CreateTable(
name: "Doctor",
columns: table => new
{
Id = table.Column<int>(nullable: false),
.
.
},
constraints: table =>
{
table.PrimaryKey("PK_Doctor", x => x.Id);
table.ForeignKey(
name: "FK_Doctor_HospitalAndClinic_HospitalAndClinicId",
column: x => x.HospitalAndClinicId,
principalTable: "HospitalAndClinic",
principalColumn: "Id",
onDelete: ReferentialAction.NoAction); // <---- Add this.
});
Or what you can also do is, as Hopeless pointed out, use fluent API to configure your model by overriding the OnModelCreating method in your derived context.
modelBuilder.Entity<Doctor>()
.HasOne(e => e.HospitalAndClinic)
.WithMany()
.OnDelete(DeleteBehavior.NoAction); // <-- Add this
Visit here to see all DeleteBehaviors and visit here to see all ReferentialActions

Unable to make the foreign key with non-primary key

I am trying to create a database called Donation within it it got this column IC its is and identity number value so I had already set it into IsUnique but somehow it still return the error message
Donation_Customers_Target_Donation_Customers_Source: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'IC' on entity 'Donation' does not match the type of property 'CustomerID' on entity 'Customers' in the referential constraint 'Donation_Customers'.
And here is the model of the Donation and Customers
Customer
[Key]
public int CustomerID { get; set; }
[Display(Name = "IC")]
[Index(IsUnique = true)]
[Required(AllowEmptyStrings = false, ErrorMessage = "IC is required")]
[MinLength(14)][MaxLength(14)]
public string IC { get; set; }
[Display(Name = "First Name")]
[Required(AllowEmptyStrings = false, ErrorMessage = "First name required")]
public string FirstName { get; set; }
Donation
[Key]
public int DonationId { get; set; }
public DateTime? TransacTime { get; set; }
public int Amount { get; set; }
public string IC { get; set; }
[ForeignKey("IC")]
public Customers Customers { get; set; }

Self-Referencing In Many-To-Many with Cascades

So I have a simple many to many relationship like below, and I have manually added onUpdate: ReferantialAction.Cascade on the foreign key part, and when I update my entitiy with a simple SqlCommand I can successfully update my entity.
public class Machine
{
public string No { get; set; }
public string Name { get; set; }
public List<MachinePart> MachineParts { get; set; }
}
public class Part
{
public string No { get; set; }
public string Name { get set; }
public List<MachinePart> MachineParts { get; set; }
}
public class MachinePart
{
public string MachineNo { get; set; }
public Machine Machine { get; set; }
public string PartNo { get; set; }
public Part Part { get; set; }
}
DbContext
builder.Entity<MachinePart>().HasKey(i => new { i.MachineNo, i.PartNo });
Migration
migrationBuilder.AddForeignKey(
name: "FK_MachineParts_Machines_MachineNo",
table: "MachineParts",
column: "MachineNo",
principalTable: "Machines",
principalColumn: "No",
onUpdate: ReferentialAction.Cascade,
onDelete: ReferentialAction.Cascade);
But now I have to cretae a SELF REFERENCING MANY TO MANY TABLE which can be a cascade relation,
public class MachineRelation
{
public string MachineNo { get; set; }
public Machine Machine { get; set; }
public string ReferencedMachineNo { get; set; }
public Machine ReferencedMachine { get; set; }
}
When I manually add
onUpdate: ReferantialAction.Cascade &&
onDelete: ReferantialAction.Cascade
I get cascade exception =>
Introducing FOREIGN KEY constraint 'FK_AssemblyRevisions_Assemblies_RevisionedAssemblyNo' on table 'AssemblyRevisions' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

EF Core Add-Migration generating extra column with ColumnName1

I have the following entities when I generate migration it creates two columns with name RestrictedCategoryId and RestrictedCategoryId1(FK). How to solve this issue to generate only one column with FK?
Note: I need OrderId in each entity.
`C#
public class Order
{
public Guid Id { get; set; }
public DateTime OrderDate { get; set; }
private List<Category> _categories;
public List<Category> Categories => _categories;
}
public class Category
{
public Guid Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public Guid OrderId { get; set; }
public Order Order { get; set; }
private List<RestrictionCategory> _restrictedCategories;
public List<RestrictionCategory> RestrictedCategories => _restrictedCategories;
}
public class RestrictionCategory
{
public Guid Id { get; set; }
public string Name { get; set; }
public Guid OrderId { get; set; }
public Order Order { get; set; }
public Guid CategoryId { get; set; }
public Category Category { get; set; }
public Guid RestrictedCategoryId { get; set; }
public Category RestrictedCategory { get; set; }
}
public class OrderConfiguration : IEntityTypeConfiguration<Order>
{
public void Configure(EntityTypeBuilder<Order> builder)
{
builder.HasKey(o => o.Id);
builder.Property(o => o.Id).IsRequired();
}
}
public class CategoryConfiguration : IEntityTypeConfiguration<Category>
{
public void Configure(EntityTypeBuilder<Category> builder)
{
builder.HasKey(c => new { c.Id, c.OrderId });
builder.Property(o => o.Id).IsRequired();
builder.Property(o => o.OrderId).IsRequired();
builder.HasMany(c => c.RestrictedCategories).WithOne(cr => cr.Category)
.HasForeignKey(cr => new { cr.CategoryId, cr.OrderId
}).OnDelete(DeleteBehavior.NoAction);
}
}
public class RestrictionCategoryConfiguration : IEntityTypeConfiguration<RestrictionCategory>
{
public void Configure(EntityTypeBuilder<RestrictionCategory> builder)
{
builder.HasKey(c => new { c.Id, c.OrderId });
builder.Property(o => o.Id).IsRequired();
builder.Property(o => o.OrderId).IsRequired();
builder.HasIndex(cr => new { cr.RestrictedCategoryId, cr.OrderId });
}
}
`
The entities resembles to actual ones.
Actually you get two additional columns:
RestrictedCategoryId = table.Column<Guid>(nullable: false),
RestrictedCategoryId1 = table.Column<Guid>(nullable: true), // <--
RestrictedCategoryOrderId = table.Column<Guid>(nullable: true) // <--
Apparently EF Core Foreign Key Conventions doesn't play well with composite keys, so you have to explicitly configure the relationship - similar to what you did for the other relationship, just since your model has no corresponding collection navigation property you have to use HasMany with generic type argument and no parameters, e.g. inside CategoryConfiguration:
builder.HasMany<RestrictionCategory>()
.WithOne(cr => cr.RestrictedCategory)
.HasForeignKey(cr => new { cr.RestrictedCategoryId, cr.OrderId})
.OnDelete(DeleteBehavior.NoAction);

Re-Creating table in migration results in 'Invalid column name User_Id'

I open this question because of this unanswered/duplicate question of mine:
Multiple identity columns specified for table exception
The answer to this question is here:
Cant remove identity attribute from PK
in short: "I have to Re-Create my sql table in the migration Up method"
I have a User has many SchoolclassCode relation:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<SchoolclassCode> SchoolclassCodes { get; set; }
}
public class SchoolclassCode
{
public int Id { get; set; }
public string Schoolclass { get; set; }
public string Type { get; set; }
public User User { get; set; }
public int UserId { get; set; }
}
That is my INIT migration
public partial class Init: DbMigration
{
public override void Up()
{
CreateTable(
"dbo.SchoolclassCodes",
c => new
{
Id = c.Int(nullable: false, identity: true),
Schoolclass = c.String(),
Type = c.String(),
User_Id = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Users", t => t.User_Id)
.Index(t => t.User_Id);
CreateTable(
"dbo.Users",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(),
})
.PrimaryKey(t => t.Id);
}
public override void Down()
{
DropForeignKey("dbo.SchoolclassCodes", "User_Id", "dbo.Users");
DropIndex("dbo.SchoolclassCodes", new[] { "User_Id" });
DropTable("dbo.Users");
DropTable("dbo.SchoolclassCodes");
}
}
That is my Second migration which is throwing the error: invalid column name 'User_Id' when I do 'Update-database'
public partial class ReCreateTable : DbMigration
{
public override void Up()
{
// backup schoolclassCodes table
DropTable("SchoolclassCodes");
CreateTable("SchoolclassCodes",
c => new
{
Id = c.Int(nullable: false, identity: true),
Schoolclass = c.String(maxLength: 3), // 12a,7b
Type = c.String(),
UserId = c.Int(nullable: false,identity:false)
})
.PrimaryKey(t => t.Id)
.ForeignKey("Users", t => t.UserId, cascadeDelete: true)
.Index(s => s.Schoolclass, unique: true);
// Delete Table Users
Sql("Delete from Users");
// Re-Insert data
SqlFile("./Migrations/data.sql");
}
public override void Down()
{
//
}
}
What do I wrong, that the update-database fails?
If you are going to delete everything you created in the first migration, drop them as described in the Down() code:
// backup schoolclassCodes table
DropForeignKey("dbo.SchoolclassCodes", "User_Id", "dbo.Users");
DropIndex("dbo.SchoolclassCodes", new[] { "User_Id" });
// DropTable("dbo.Users");
DropTable("dbo.SchoolclassCodes");
An observation, seems like you are coupling the need to keep your old data with migrations. I would separate the two.
First, save your old data. If the volume is low consider adding it to a Seed() method. Otherwise rename the tables in SQL and use SQL to repopulate them after migrations adds the corrected tables back.
Migrations are intended to let you build a database from your models, so I would delete both migrations and add a single new migration that represents your current model.

Resources