How solve Microsoft.EntityFrameworkCore.DbUpdateException [duplicate] - asp.net-core

This question already has answers here:
I got error "The DELETE statement conflicted with the REFERENCE constraint"
(5 answers)
Closed last month.
public class HeadDoctor
{
public int Id { get; set; }
public int DoctorId { get; set; }
public Doctor Doctor { get; set; }
public int? InstitutionId { get; set; }
public Institution? Institution { get; set; }
}
public class Institution
{
public int Id { get; set; }
public string? Name { get; set; }
public HeadDoctor HeadDoctor { get; set; }
}
In DbContext:
builder.Entity<Institution>()
.HasOne(institution => institution.HeadDoctor)
.WithOne(headDoctor => headDoctor.Institution)
.HasForeignKey<HeadDoctor>(headDoctor => headDoctor.InstitutionId);
Error:
SqlException: The DELETE statement conflicted with the REFERENCE constraint "FK_HeadDoctor_Institution_InstitutionId". The conflict occurred in database "MedicDb", table "dbo.HeadDoctor", column 'InstitutionId'.
How to fix this error?

The error means that you have data in other tables that references the data you are trying to delete.
This is asimilar thread
You would need to drop and recreate the constraints.

Related

How to create two one-to-one relations with same entity in Entity Framework Core [duplicate]

This question already has answers here:
Entity Framework Code First - two Foreign Keys from same table
(7 answers)
Closed 3 years ago.
I'm getting stuck when using code-first in EF Core 2.2.
I have an entity called: AirSensor which I need to have two one-to-one relations to TemperatureSensors, as the AirSensor is capable of read Temperature and dew point temperature.
Therefore my code is here:
public class AirSensor
{
public long AirSensorId { get; set; }
public TemperatureSensor TemperatureSensor { get; set; }
public HumiditySensor Humidity { get; set; }
public Enthalpy EnthalpyCalc { get; set; }
public TemperatureSensor DewPointTemperatureSensor { get; set; }
public long TemperatureSensorId { get; set; }
public long HumiditySensorId { get; set; }
public long EnthalpyId { get; set; }
public long DewPointTemperatureSensorId { get; set; }
}
And Temperature Entity is:
public class TemperatureSensor
{
public long TemperatureSensorId { get; set; }
public string Name { get; set; }
public float CurrentValue { get; set; }
public DateTime LastUpdated { get; set; }
public ICollection<TemperatureMeasurement> Measurements { get; set; }
}
When I add the migration everything is ok, but when updating the database it fails:
Failed executing DbCommand (17ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
ALTER TABLE [AirSensors] ADD CONSTRAINT [FK_AirSensors_TemperatureSensors_DewPointSensorId] FOREIGN KEY ([DewPointSensorId]) REFERENCES [TemperatureSensors] ([TemperatureSensorId]) ON DELETE CASCADE;
System.Data.SqlClient.SqlException (0x80131904): Si especifica la restricción FOREIGN KEY 'FK_AirSensors_TemperatureSensors_DewPointSensorId' en la tabla 'AirSensors', podrían producirse ciclos o múltiples rutas en cascada. Especifique ON DELETE NO ACTION o UPDATE NO ACTION, o bien modifique otras restricciones FOREIGN KEY.
However, I don't see the problem here, I just want to have two separate one-to-one relations.
What am I missing?
Many thanks in advance!
Configure AirSensor with Fluent API as follows:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<AirSensor>().HasOne(ars => ars.TemperatureSensor)
.WithOne().HasForeignKey<AirSensor>(ars => ars.TemperatureSensorId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<AirSensor>().HasOne(ars => ars.DewPointTemperatureSensor)
.WithOne().HasForeignKey<AirSensor>(ars => ars.DewPointTemperatureSensorId)
.OnDelete(DeleteBehavior.Restrict);
}
Now it will work as expected!

EntityFramework Trying to create multiple links to the same table, FK Constraint error

I have a table called DeliveryRequest and another table called Operator, table DeliveryRequest is as follows:
public class DeliveryRequest
{
public int ID { get; set; }
public DateTime Date { get; set; }
public string UserID { get; set; }
public string Waybill { get; set; }
public string Reference { get; set; }
public int SupplierID { get; set; }
public Supplier Supplier { get; set; }
//[ForeignKey("Operator")]
public int SenderID { get; set; }
public Operator Sender { get; set; }
//[ForeignKey("Operator")]
public int ReceiverID { get; set; }
public Operator Receiver { get; set; }
public string Origin { get; set; }
public string Destination { get; set; }
public int ServiceID { get; set; }
public Service Service { get; set; }
}
And table Operator is as follows:
public class Operator
{
public int ID { get; set; }
public string Company { get; set; }
public int ContactID { get; set; }
public Contact Contact { get; set; }
public int AddressID { get; set; }
public Address Address { get; set; }
}
So the problem is, when I am trying to update my database I get a FK Constraint error as follows:
Introducing FOREIGN KEY constraint
'FK_dbo.DeliveryRequests_dbo.Operators_SenderID' on table
'DeliveryRequests' may cause cycles or multiple cascade paths. Specify
ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN
KEY constraints.
Could not create constraint or index. See previous errors.
And the previous error is the same. As follows:
System.Data.SqlClient.SqlException (0x80131904): Introducing FOREIGN
KEY constraint 'FK_dbo.DeliveryRequests_dbo.Operators_SenderID' on
table 'DeliveryRequests' may cause cycles or multiple cascade paths.
Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other
FOREIGN KEY constraints.
Focus on the Sender and Receiver part, I am no expert but the error must be there lol
//[ForeignKey("Operator")]
public int SenderID { get; set; }
public Operator Sender { get; set; }
//[ForeignKey("Operator")]
public int ReceiverID { get; set; }
public Operator Receiver { get; set; }
It looks like you are using Code First approach. So try to turn off CascadeDelete for DeliveryRequests:
modelBuilder.Entity<DeliveryRequests>()
.HasRequired(c => c.Operator )
.WithMany()
.WillCascadeOnDelete(false);
For example:
public class YourDBContext: DbContext
{
public YourDBContext(): base()
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<DeliveryRequests>()
.HasRequired(c => c.Operator )
.WithMany()
.WillCascadeOnDelete(false);
}
}

Error with EF core savecontext using Identity class

I have a quiz sql schema and I am also using ASP.NET Identity. When I attempt to insert an answer from the user into the UserAnswer table I get the error below. It seems like it is trying to insert into the User table but I don't want that?
Violation of PRIMARY KEY constraint 'PK_AspNetUsers'. Cannot insert
duplicate key in object 'dbo.AspNetUsers'. The duplicate key value is
(71ddfebf-18ba-4214-a01e-42ca0f239804). Cannot insert explicit value
for identity column in table 'Questions' when IDENTITY_INSERT is set
to OFF. The statement has been terminated.
foreach (ProfileViewModel pvm in profileViewModels)
{
UserAnswer ua = new UserAnswer();
ua.QuestionId.ID = pvm.Question.ID;
ua.ApplicationUser.Id = userId;
ua.AnswerText = pvm.Answer;
_userAnswerRepository.Create(ua);
}
which just does
protected void Save() => _context.SaveChanges();
and the model is
public class UserAnswer
{
public UserAnswer()
{
this.QuestionId = new Question();
this.ApplicationUser = new ApplicationUser();
}
public int Id { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public Question QuestionId { get; set; }
public string AnswerText { get; set; }
}
I guess I need to use virtual and not the actual object for some reason.. The model looked fine but it seems to confused the update
public class UserAnswer
{
public UserAnswer()
{
this.Question = new Question();
this.User = new ApplicationUser();
}
public int Id { get; set; }
public string UserId { get; set; } // FK to ApplicationUser
public int QuestionId { get; set; } // FK to Question
public string AnswerText { get; set; }
public virtual Question Question { get; set; }
public virtual ApplicationUser User { get; set; }
}

ASP EF7 Set column value in migration

I want to move from autoincrement ids to composite primary keys. So, these two entities
public class SeasonTeam
{
public int SeasonTeamId { get; set; }
public int SeasonId { get; set; }
public int TeamId { get; set; }
}
public class GroupEntry
{
public int GroupEntryId { get; set; }
public int SeasonTeamId { get; set; }
public SeasonTeam SeasonTeam { get; set; }
}
will now look like this
public class SeasonTeam
{
public int SeasonId { get; set; }
public int TeamId { get; set; }
}
public class GroupEntry
{
public int GroupEntryId { get; set; }
public int SeasonId { get; set; }
public int TeamId { get; set; }
public SeasonTeam SeasonTeam { get; set; }
}
Visual Studio generated migration code, but it corrupts data.
migrationBuilder.AddColumn<int>(
name: "SeasonId",
table: "GroupEntry",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "TeamId",
table: "GroupEntry",
nullable: false,
defaultValue: 0);
migrationBuilder.DropForeignKey(name: "FK_GroupEntry_SeasonTeam_SeasonTeamId", table: "GroupEntry");
migrationBuilder.DropPrimaryKey(name: "PK_SeasonTeam", table: "SeasonTeam");
migrationBuilder.DropColumn(name: "SeasonTeamId", table: "SeasonTeam");
Default value 0 obviously won't work, I need ids from referenced SeasonTeam table, but I didn't find any examples. How can I set proper id values for a new composite key before I delete old primary key column?
You can't do this programmatically with EF's APIs, however, if you can write the SQL to move the values from one table to another, you can add a custom migration step after the Add column operations and before the drop column operations.
migrationBuilder.Sql(#"INSERT INTO ...(your SQL here)");
From the limited info in your question, I can't tell you what that SQL should be.

How to Insert data in table when Foreign Key is not a primary key

I created a Model with Entity Framework Code First and have two classes
Product.cs
public class Product
{
public Product()
{
Certificates = new HashSet<Certificate>();
}
public int ProductId { get; set; }
public int ProductCode { get; set; }
public decimal Price { get; set; }
public string Type { get; set; }
public string SubType { get; set; }
public int RelatedProductId { get; set; }
public string Description { get; set; }
public string DescriptionSpanish { get; set; }
public string ShortDescription { get; set; }
public string CertificateDescription { get; set; }
public string QBItemCode { get; set; }
public string QBDescCode { get; set; }
public virtual ICollection<Certificate> Certificates { get; set; }
}
Certificate.cs
public class Certificate
{
public int CertificateId { get; set; }
public string Type { get; set; }
public string Course { get; set; }
public DateTime DateGranted { get; set; }
public string NameOnCertificate { get; set; }
public int FinalExamQuestionsCorrect { get; set; }
public int FinalExamQuestionsTotal { get; set; }
public string ClientIPAddress { get; set; }
public int ProductCode { get; set; }
public virtual Product Product { get; set; }
public string UserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
}
ProductConfiguration.cs
public class ProductConfiguration : EntityTypeConfiguration<Product>
{
public ProductConfiguration()
{
HasKey(p => p.ProductId);
Property(p => p.ProductId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(p => p.ProductCode)
.HasColumnAnnotation("Index",
new IndexAnnotation(new IndexAttribute("AK_Product_ProductCode") { IsUnique = true }));
}
}
CertificateConfiguration.cs
public class CertificateConfiguration : EntityTypeConfiguration<Certificate>
{
public CertificateConfiguration()
{
HasKey(c => c.CertificateId);
Property(c => c.CertificateId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(p => p.ProductCode).HasColumnName("ProductId");
HasRequired(c => c.ApplicationUser)
.WithMany(u => u.Certificates)
.HasForeignKey(c => c.UserId);
HasRequired(c => c.Product)
.WithMany(p => p.Certificates)
.HasForeignKey(c => c.ProductCode);
}
}
Notice, I created a Foreign Key ProductCode (rename it to ProductId) in Certificate Table.
I also seeded Product table with some data in which the ProductId generated by database and ProductCode that I manually defined. The problem is when I am trying to insert a record in Certificate table by running a sql query in which I defined a foreign key that's actually a ProductCode (not ProductId), it throws an error
SQL QUERY:
Insert into [dbo].[Certificates]
values (
'TestType','TestCourse',GETUTCDATE(),'TestName',1,5,
'127.0.0.1',201,'userId'
)
201 is the ProductCode in query that exist in Product table
Error
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Certificates_dbo.Products_ProductId". The conflict occurred in database "myDatabse", table "dbo.Products", column 'ProductId'.
I am not sure why it's looking for Primary Key ProductId. It should look for the ProductCode in Product table weather it exist or not.
I believe you're running into a limitation of EF whereby your FK on the dependent end of the relationship has to refer back to the PK on the principal end. When you configure the relationship between Product and Certificates here:
HasRequired(c => c.Product)
.WithMany(p => p.Certificates)
.HasForeignKey(c => c.ProductCode);
this establishes the foreign key relationship between the Product primary key - Product.ProductId - and the foreign key you defined - Certificate.ProductCode (named Certificate.ProductId in your table).
While the database will support FK referring back to a unique key in your table, EF does not support it (at this time).
Here are a few other SO questions that cover this issue:
How to get EF6 to honor Unique Constraint (on FK) in Association/Relationship multiplicity?
Database first Entity Framework mapping unique foreign keys as one to many
And here's the official feature request to add this feature to EF:
Unique Constraint (i.e. Candidate Key) Support
According to the comments, it looks like they are working adding this in EF7.