.NET Core Code First模式下存储列表到数据库及一对多关联操作疑问
一对多实体关联与数据操作说明(EF Core场景)
关联原理
你当前的写法是EF Core中约定式一对多关系的标准定义,核心逻辑如下:
- 主类中的
List<Addresses> ClientAddress是导航属性,仅用于代码层面的关联操作,不会作为字段存储到主表中 - 两张表的关联核心是从表(Addresses表)的外键字段:你需要先在Addresses类中新增关联主实体的外键字段(假设主实体类名为Client,字段为
public string ClientId { get; set; }),主表的Id值会存储在这个外键字段中,完成一对多关系的绑定 - EF Core会自动识别导航属性和外键的对应关系,查询主实体时会自动匹配从表中外键符合的记录,填充到
ClientAddress列表中
小提示:你当前主类的Name属性类型写为double?,正常名称字段应为string类型,大概率是笔误建议修正;另外地址类名拼写为Adresses,标准复数拼写为Addresses,也建议修正避免拼写错误
关联配置方法
如果EF Core没有自动识别到关系,可以通过两种方式显式配置:
- 数据注解方式
在Addresses类中新增反向导航属性和外键,加对应注解即可:
public class Addresses { public string Id { get; set; } = default!; public string Address { get; set; } = default!; // 新增外键 public string ClientId { get; set; } = default!; // 新增反向导航属性 public Client Client { get; set; } = default!; }
在主类的导航属性上增加InverseProperty注解:
[InverseProperty(nameof(Addresses.Client))] public List<Addresses> ClientAddress { get; set; } = default!;
- FluentAPI方式
在DbContext的OnModelCreating方法中配置关系:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Client>() .HasMany(c => c.ClientAddress) // 主实体对应多个地址 .WithOne(a => a.Client) // 每个地址对应一个主实体 .HasForeignKey(a => a.ClientId) // 地址表的外键字段 .OnDelete(DeleteBehavior.Cascade); // 可配置删除行为,比如级联删除 }
Address表插入数据操作逻辑
分两种常见场景:
场景1:新增主实体时同时新增关联地址
直接给主实体的导航属性赋值即可,EF Core会自动先插入主表数据,拿到主表Id后自动赋值给地址的外键字段,再插入地址表,无需手动处理外键:
var newClient = new Client { Id = Guid.NewGuid().ToString(), Name = "张三", FamilyName = "张", ClientAddress = new List<Addresses> { new Addresses { Id = Guid.NewGuid().ToString(), Address = "北京市朝阳区XX路" }, new Addresses { Id = Guid.NewGuid().ToString(), Address = "上海市浦东新区XX路" } } }; dbContext.Clients.Add(newClient); await dbContext.SaveChangesAsync();
场景2:给已存在的主实体新增地址
有两种实现方式:
- 方式1:通过导航属性新增,无需手动赋值外键
// 先查询到对应的已存在主实体 var existClient = await dbContext.Clients.FirstOrDefaultAsync(c => c.Id == "目标客户的Id"); // 直接往导航属性列表里加新地址 existClient.ClientAddress.Add(new Addresses { Id = Guid.NewGuid().ToString(), Address = "广州市天河区XX路" }); await dbContext.SaveChangesAsync();
- 方式2:直接赋值外键插入,性能更高无需查询主表
var newAddress = new Addresses { Id = Guid.NewGuid().ToString(), Address = "深圳市南山区XX路", ClientId = "已存在的目标客户Id" // 手动赋值外键即可 }; dbContext.Addresses.Add(newAddress); await dbContext.SaveChangesAsync();
内容的提问来源于stack exchange,提问作者moris62
相关产品推荐
相关产品推荐

