c# - EF Core 处理影子外键 DeleteBehaviour
问题描述
我希望能够在删除影子外键属性的相关实体时更改行为。
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; }
}
此设置将在图书实体中创建一个影子属性“AuthorId”,并且可以根据需要为空。现在我希望当我删除一个作者时,所有相关书籍都将“AuthorId”外键设置为null
. 我怎样才能做到这一点?
解决方案
只需在 DbContext 中配置删除行为:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>()
.HasOne<Author>()
.WithMany(a => a.Books)
.HasForeignKey("AuthorId")
.OnDelete(DeleteBehavior.SetNull);
base.OnModelCreating(modelBuilder);
}
例如:
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();
}
}
}
}
对于 SQL Server,这是生成的 Book 表:
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
);
推荐阅读
- webpack - 在 SCSS 图像路径前添加 CDN URL
- django - Django 数据保存在数据库中但未显示在模板中
- javascript - 如何使用 javascript 让 HTML div 元素循环?
- php - 从 webhook 请求中提取表单字段
- python-3.x - 如何从 ttkwidgets 禁用/启用 ScaleEntry?
- singularity-container - 如何在 Singularity 中导出容器
- reactjs - React 组件只显示状态码错误消息而不是自定义的
- javascript - 根据 uniqueValues 过滤对象数组
- c# - 在方法上下文中使用 Dapper 返回多个列表
- c# - 尝试重新创建已删除的 DynamoDB 表时,为什么我的表创建失败?