Entity Framework Core 笔记:具有 required 标识,且仅有 inititor 的导航 ID 属性是否会影响 EF Core 更新?

注意,本文以 Entity Framework Core 9 为基准进行测试。

省流

当外键属性未提供 Setter 时,EF Core 仍然可以为其更新外键实体 Id,不会受到影响。

详细探讨

在使用 EF Core 操作数据库时,我根据实体的设计目的,将实体设计为如下:

public class Entity
{
    public long Id { get; init; }

    // 主角, 关联的子实体类和它的外键属性.
    public required SubEntity SubEntity { get; init; } = null!;
    public required long SubEntityId { get; init; }
}

public class SubEntity
{
    public long Id { get; init; }
    public required string Name { get; init; }
}

然后我将 DbContext 设计为:

public class AppDbContext : DbContext
{

    public DbSet<Entity.Entity> Entities { get; internal init; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // 示例代码所使用的数据库.
        optionsBuilder.UseSqlite("Data Source=./app.db");
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        // 设置 Entity 与 SubEntity 的关系.
        builder.Entity<Entity.Entity>()
            .HasOne(e => e.SubEntity)
            .WithOne()
            .HasForeignKey<Entity.Entity>(g => g.SubEntityId)
            .OnDelete(DeleteBehavior.Restrict);
    }
}

由于 SubEntity 会跟着 Entity 一起创建,因此我会先将 SubEntity 创建好,并设置到 Entity.SubEntity 属性中,但由于 Entity.SubEntityId 是 required 的,因此在创建实体实例时,我将其设为了 0,就像这样:

var subEntity = new SubEntity
{
    Name = "SubEntity 1"
};

var entity = new Entity.Entity
{
    SubEntity = subEntity,
    SubEntityId = 0
};

那么,当 Entity 被保存时,EF Core 是否能更新 Entity.SubEntityId 属性呢?因此我们调整一下测试代码(这里使用顶层代码以简化代码):

using EF_Core_Test_01.Data;
using EF_Core_Test_01.Entity;

var dbContext = new AppDbContext();
        
var subEntity = new SubEntity
{
    Name = "SubEntity 1"
};

var entity = new Entity
{
    SubEntity = subEntity,
    SubEntityId = 0
};
        
Console.WriteLine($"Before Add Entity Id: {entity.Id}");
Console.WriteLine($"Before Add SubEntity Id Attribute: {entity.SubEntityId}");

dbContext.Entities.Add(entity);
        
Console.WriteLine($"Before Saves Entity Id: {entity.Id}");
Console.WriteLine($"Before Saves SubEntity Id Attribute: {entity.SubEntityId}");
        
dbContext.SaveChanges();
        
Console.WriteLine($"After Saves Entity Id: {entity.Id}");
Console.WriteLine($"After Saves SubEntity Id Attribute: {entity.SubEntityId}");

最后我们来看一下控制台输出:

Before Add Entity Id: 0
Before Add SubEntity Id Attribute: 0
Before Saves Entity Id: 0
Before Saves SubEntity Id Attribute: 0
After Saves Entity Id: 2
After Saves SubEntity Id Attribute: 2

可以从控制台输出看到,当执行 DbContext.SaveChanges() 时,Entity 和 SubEntity 都会得到数据库生成的 Id,并且 Entity.SubEntityId 已经被更新为 SubEntity 的 Id,因此即使外键导航属性未设置 Setter 也不会影响 EF Core 更新。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇