Entity Framework Core 7 Does not allow nullable foreign Key

735 Views Asked by At

The thing that i want to achieve is when a category deleted related column in the book, that categoryId must change as null, i write a delete behaviour method with set null. However, a nullable property problem occured

I am following code first approach Firstly, i defined a book entity with a categoryId variable this will behave as a foreign key also put a question mark to determine it could be null. This was ok, I could get a file like this

// some codes here
migrationBuilder.AlterColumn<int>(
                name: "CategoryId",
                table: "Books",
                type: "int",
                nullable: true,
                oldClrType: typeof(int),
                oldType: "int");

// some codes here

However when i have added to delete behaviour method, the nullable part of the code was changed as false automatically,

// some codes here
migrationBuilder.AlterColumn<int>(
                name: "CategoryId",
                table: "Books",
                type: "int",
                nullable: false,
                defaultValue: 0,
                oldClrType: typeof(int),
                oldType: "int",
                oldNullable: true);
// some codes here

I think that I am missing something, finally when i apply "update-database" command from console an error appears

"Cannot create the foreign key "FK_Books_Categories_CategoryId" with the SET NULL referential action, because one or more referencing columns are not nullable. Could not create constraint or index. See previous errors"

The previous part is

"Failed executing DbCommand (6ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] ALTER TABLE [Books] ADD CONSTRAINT [FK_Books_Categories_CategoryId] FOREIGN KEY ([CategoryId]) REFERENCES [Categories] ([CategoryId]) ON DELETE SET NULL;"

That one is the book class

public class Book : IEntity
    {        
        public int BookId { get; set; }
        public string Title { get; set; }
        public DateTime CreatedDate { get; set; }
        public decimal Price { get; set; }

        //  foreign key 
        public int? CategoryId { get; set; }

        //  Simple navigation property
        public Category Category { get; set; }

        //  Navigation property
        public BookDetail BookDetail { get; set; }

    }

Category class

public class Category : IEntity
    {
        public int CategoryId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }

        //Collection Navigation Property
        public ICollection<Book> Books { get; set; }

    }

BookMap

public class BookMap : IEntityTypeConfiguration<Book>
    {
        public void Configure(EntityTypeBuilder<Book> builder)
        {
            builder.HasKey(b => b.BookId);

            builder.Property(b => b.Title)
                   .IsRequired()
                   .HasMaxLength(250);

            builder.Property(b => b.CreatedDate)
                   .HasDefaultValueSql("GETDATE()");

            builder.Property(b => b.BookId)
                   .IsRequired();

            builder.HasData(
                new Book { BookId = 1, Title = "Devlet", CategoryId = 2 },
                new Book { BookId = 2, Title = "Tutunamayanlar", CategoryId = 2 },
                new Book { BookId = 3, Title = "Yeşil Yol", CategoryId = 2 }
                );

            
            builder.HasOne(b => b.Category)
                   .WithMany(c => c.Books)
                   .HasForeignKey(b => b.CategoryId)
                   .OnDelete(DeleteBehavior.SetNull);      

        }
    }

Category Map

public class CategoryMap : IEntityTypeConfiguration<Category>
    {
        public void Configure(EntityTypeBuilder<Category> builder)
        {
            builder.HasKey(c => c.CategoryId);

            builder.Property(c => c.Name)
                   .IsRequired()
                   .HasMaxLength(200);

            builder.Property(c => c.Description)
                   .HasDefaultValue("No Info");

            builder.HasData(
                new Category() { CategoryId = 1, Name = "History"},
                new Category() { CategoryId = 2, Name = "Novel"}
                );
        }
    }

Thanks for your help

0

There are 0 best solutions below