I want to be able to change the behaviour when deleting a related entity for a shadow foreign key property.
public class Author
{
public int AuthorId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Book> Books { get; set; }
}
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
}
This setup will create a shadow property "AuthorId" in the book entity and is nullable as I want. Now I'd like that when I delete an author, all the related books will set the "AuthorId" foreign key to null
. How can I achieve this?
Just configure the delete behavior in the DbContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>()
.HasOne<Author>()
.WithMany(a => a.Books)
.HasForeignKey("AuthorId")
.OnDelete(DeleteBehavior.SetNull);
base.OnModelCreating(modelBuilder);
}
eg:
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
namespace EfCore3Test
{
public class Author
{
public int AuthorId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Book> Books { get; } = new HashSet<Book>();
}
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
}
public class Db : DbContext
{
public DbSet<Author> Authors { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>()
.HasOne<Author>()
.WithMany(a => a.Books)
.HasForeignKey("AuthorId")
.OnDelete(DeleteBehavior.SetNull);
base.OnModelCreating(modelBuilder);
}
public static readonly ILoggerFactory MyLoggerFactory
= LoggerFactory.Create(builder => { builder.AddConsole(); });
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=localhost;Database=EFCore3Test;Integrated Security = true", a => a.UseRelationalNulls(true))
.ConfigureWarnings(c => c.Log((RelationalEventId.CommandExecuting, LogLevel.Information)))
.UseLoggerFactory(MyLoggerFactory);
base.OnConfiguring(optionsBuilder);
}
}
class Program
{
static void Main(string[] args)
{
using (var db = new Db())
{
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
var a = new Author();
for (int i = 0; i < 10; i++)
{
var b = new Book();
a.Books.Add(b);
}
db.Authors.Add(a);
db.SaveChanges();
}
using (var db = new Db())
{
var a = db.Authors.First();
db.Authors.Remove(a);
db.SaveChanges();
}
}
}
}
For SQL Server this is the resulting Book table:
CREATE TABLE [Book] (
[BookId] int NOT NULL IDENTITY,
[Title] nvarchar(max) NULL,
[AuthorId] int NULL,
CONSTRAINT [PK_Book] PRIMARY KEY ([BookId]),
CONSTRAINT [FK_Book_Authors_AuthorId] FOREIGN KEY ([AuthorId]) REFERENCES [Authors] ([AuthorId]) ON DELETE SET NULL
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.