一对多返回空数组

kzm*_*jak 4 c# entity-framework-core asp.net-core

我正在尝试以一对多关系连接两个对象,Workplace 可以容纳多个 People,而一个 Person 只能拥有一个 Workplace。

当我执行此代码片段并检查结果时,p1 已正确将 w1 指定为 p1.Workplace,但 w1.employees 的人员列表始终为空。

即使我将 w1 分配给 p1.Workplace 之后,是否还必须手动将 p1 添加到 w1.Employees 中?

SeedData.cs(代码片段)

var w1 = new Workplace
{
   EntryCode = "1111"
   //[...] other data I cut out for brievity
};
context.Workplaces.Add(w1);

Person p1 = new Person
{
    Name = "Spencer",
    Workplace = w1
   //[...] other data I cut out for brievity
};
context.Person.Add(p1)
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

工作场所.cs

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace Counsel.Models
{
    [Table("Workplace")]
    public class Workplace
    {
        [Column("WorkplaceId")]
        public int WorkplaceId {get;set;}

        [Column("EntryCode")]
        public string EntryCode {get;set;}

        [Column("ConfirmationCode")]
        public string ConfirmationCode {get;set;}

        [Column("Employees")]
        public ICollection<Person> Employees {get;set;}
    }
}
Run Code Online (Sandbox Code Playgroud)

人物.cs

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace Counsel.Models
{
    public class Person
    {
        [Column("PersonId")]
        public int PersonId {get;set;}

        [Column("Image")]
        public string Image {get;set;}

        [Column("FName")]
        public string FName { get; set; }

        [Column("LName")]
        public string LName {get;set;}

        [Column("Role")]
        public string Role {get;set;}

        [Column("Email")]
        public string Email {get;set;}

        [Column("Password")]
        public string Password {get;set;}

        public Workplace Workplace {get;set;} = new Workplace();
        public ICollection<ChatPerson> Chats {get;set;}
    }
}
Run Code Online (Sandbox Code Playgroud)

数据上下文.cs

using Counsel.Models;
using Microsoft.EntityFrameworkCore;

namespace Counsel.Models {
    public class DataContext : DbContext
    {
        public DataContext(DbContextOptions<DataContext> opts): base(opts){}

        public DbSet<Person> People {get;set;}
        public DbSet<Workplace> Workplaces {get;set;}


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            modelBuilder.Entity<Person>((item)=>{
                item.HasKey(p => p.PersonId);
                item.HasOne<Workplace>(p => p.Workplace).WithMany(w => w.Employees).OnDelete(DeleteBehavior.SetNull);
            });


            modelBuilder.Entity<Workplace>((item)=>{
                item.HasKey(p => p.WorkplaceId);
                item.HasMany<Person>(w => w.Employees).WithOne(p => p.Workplace).OnDelete(DeleteBehavior.Cascade);
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

WorkplaceController.cs(代码片段)

[HttpGet("{id}")]
        public Workplace GetWorkplace(int id)
        {
           return context.Workplaces
                .Where(c => c.WorkplaceId == id)
                .Include(c => c.Employees).ThenInclude(c => c.Workplace)
                .FirstOrDefault();

        }
Run Code Online (Sandbox Code Playgroud)

GetWorplace() 输出

[
  {
    "workplaceId": 1,
    "entryCode": "1111",
    "confirmationCode": "1111",
    "employees": [

    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,“employees”数组是空的,尽管 p1 应该在那里。

Iva*_*oev 7

该问题是由引用导航属性初始值设定项引起的:

public Workplace Workplace { get; set; } = new Workplace(); // <--
Run Code Online (Sandbox Code Playgroud)

切勿这样做 - 它会混淆 EF 导航属性修复并导致意外的运行时行为。

请注意,初始化集合导航属性是可以的,尽管不是必需的。这是因为null在引用导航属性中具有特殊含义,并且确实提供了到主体实体的链接,主体实体可能包含也可能不包含依赖实体的集合。

很快,删除初始化程序

public Workplace Workplace { get; set; }
Run Code Online (Sandbox Code Playgroud)

问题就会得到解决。