I need to insert an enitity into the database that has a constraint on it's id, so I want to set it manually.
Note: The model below is the minimal example to get the idea of what I'm doing. The whole thing is running on ASP.NET Core 2 with EF Core and Pomelo MySql provider.
I'm trying to create an entity in my already existing database (MySQL) that is defined like this:
CREATE TABLE Users (
id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(128) NOT NULL);
CREATE TABLE UserData (
id INTEGER PRIMARY KEY,
name VARCHAR(32) NOT NULL,
FOREIGN KEY(id) REFERENCES Users(id));
So each record in the Users
table has a record in the UserData
table.
Now in my code I want to use something like
Context.Users.Add(user);
Context.SaveChanges();
data.Id = user.Id;
Context.UserData.Add(data);
Context.SaveChanges();
The User
should get their Id
generated by the database and then their UserData
created with that Id
. However, the statement executed by EF results in an error:
Failed executing DbCommand (6ms) [Parameters=[@p0='?', @p1='?' (Size = 32)], CommandType='Text', CommandTimeout='30']
INSERT INTO `UserData` (`id`, `name`)
VALUES (@p0, @p1);
MySql.Data.MySqlClient.MySqlException: Cannot add or update a child row:
a foreign key constraint fails (`Main`.`UserData`, CONSTRAINT `UserData_ibfk_1`
FOREIGN KEY (`id`) REFERENCES `Users` (`id`))
Which means that whatever Id
is passed to MySQL it's not the one of User
.
I even tried adding a [DatabaseGenerated(DatabaseGeneratedOption.None)]
to the UserData.Id
as suggested in Entering keys manually with Entity Framework, but I'm thinking that is more with regard to CodeFirst approach rather than having an already running database.
From this question: EF Core Add function returns negative id I learned that Context.Add()
modifies the Id
, but assigning my value after Add
doesn't change anything.
In case it's important, here's my DbContext Configuration
modelBuilder.Entity<UserData>(entity =>
{
entity.Property(e => e.Id)
.HasColumnName("id")
.HasColumnType("int(11)")
.ValueGeneratedNever();
entity.Property(e => e.Name)
.IsRequired()
.HasColumnName("name")
.HasMaxLength(32);
entity.HasOne(d => d.User)
.WithOne(p => p.UserData)
.HasForeignKey<UserData>(d => d.Id)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("UserData_ibfk_1");
}
modelBuilder.Entity<User>(entity =>
{
entity.Property(e => e.Id)
.HasColumnName("id")
.HasColumnType("int(11)")
.ValueGeneratedNever();
entity.Property(e => e.Email)
.IsRequired()
.HasColumnName("email")
.HasMaxLength(128);
}