EntityFrameworkCore, insert records in a table containing a foreign key

1.5k Views Asked by At

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

0

There are 0 best solutions below