I'm a newbie for IdentityFramework (both the Core Version and the older ones...) and I really don't get this: I'm in a "database first" situation, with these 2 linked table in the db: the items table has a foreign key towards the colours table. Both of them have and Id IDENTITY PRIMARY KEY
CREATE TABLE [dbo].[colours](
[id] [int] IDENTITY(1,1) NOT NULL,
[description] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_colours] PRIMARY KEY
CREATE TABLE [dbo].[items](
[id] [int] IDENTITY(1,1) NOT NULL,
[description] [nvarchar](50) NULL,
[colour_id] [int] NOT NULL,
CONSTRAINT [PK_items] PRIMARY KEY
ALTER TABLE [dbo].[items] WITH CHECK ADD CONSTRAINT [FK_items_colours] FOREIGN KEY([colour_id])
REFERENCES [dbo].[colours] ([id])
ON UPDATE CASCADE
I generated the model and the dbContext class with the Scaffold-DbContext utility, and that's what I obtained:
namespace GeaCollection.Data.Models
{
public partial class Colours
{
public Colours()
{
Items = new HashSet<Items>();
}
public int Id { get; set; }
public string Description { get; set; }
public virtual ICollection<Items> Items { get; set; }
}
}
namespace GeaCollection.Data.Models
{
public partial class Items
{
public int Id { get; set; }
public string Description { get; set; }
public int ColourId { get; set; }
public virtual Colours Colour { get; set; }
}
}
And that's the code snippet of the dbContext class:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Colours>(entity =>
{
entity.ToTable("colours");
entity.Property(e => e.Id)
.HasColumnName("id");
entity.Property(e => e.Description)
.IsRequired()
.HasColumnName("description")
.HasMaxLength(50);
});
modelBuilder.Entity<Items>(entity =>
{
entity.ToTable("items");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.ColourId).HasColumnName("colour_id");
entity.Property(e => e.Description)
.HasColumnName("description")
.HasMaxLength(50);
entity.HasOne(d => d.Colour)
.WithMany(p => p.Items)
.HasForeignKey(d => d.ColourId)
.OnDelete(DeleteBehavior.Restrict)
.HasConstraintName("FK_items_colours");
});
Now say a method in a Web API controller gets a serialized JSON containing an Item (complete of the colour, one that I already have in the db), and I have to insert it in the db.
{
"id": 0,
"description": "item 1",
"colour": {
"id": 2,
"description": "colour 2",
}
}
private void test()
{
// the model remapped object
var item = new Items
{
Description = "Item 1",
Colour = new Colours { Id = 2, Description = "Colour 2" }
};
dbContext.Add(item);
dbContext.SaveChanges();
}
After the Add method the item ColourId properties is properly valorized, but when I invoke the SaveChanges I get the following exception:
'Microsoft.EntityFrameworkCore.DbUpdateException':
Quando IDENTITY_INSERT è OFF non è possibile inserire un valore esplicito per la colonna Identity nella tabella 'colours'.
That is "when IDENTITY_INSERT is OFF you can't insert an explicit value for the Identity column of the 'colours' table".
For sure, I don't want to INSERT anything but the item record, and I thought the framework could match the existing colours in the linked table by itself.
If I set directly the ColourId properties, and let NULL the Colour object, I can insert the record, but to me it looks quite weird.
What am I doing wrong?
Thank you Giovanni