类型类的 DbSet 属性返回 null

Posted

技术标签:

【中文标题】类型类的 DbSet 属性返回 null【英文标题】:DbSet property of type class returns null 【发布时间】:2021-10-03 14:44:03 【问题描述】:

我正在为应用创建 API。我遇到问题的 DbContext 如下所示:

public class SchoolPlannerDbContext : DbContext

    public SchoolPlannerDbContext(DbContextOptions<SchoolPlannerDbContext> options) : base(options)  
    public DbSet<Activity> Activities  get; set; 
    public DbSet<Room> Rooms  get; set; 
    public DbSet<Subject> Subjects  get; set; 
    public DbSet<Teacher> Teachers  get; set; 
    public DbSet<Group> Groups  get; set; 


Activity类如下:

public class Activity
    
        public int ID  get; set; 

        [Required]
        public Teacher Teacher  get; set; 

        [Required]
        public Room Room  get; set; 

        [Required]
        public Subject Subject  get; set; 

        [Required]
        public Group Group  get; set; 

        [Required]
        public int Slot  get; set; 

        [Required]
        public int Day  get; set; 
    

所有其他属性都包含一个 int ID 和一个字符串 Name。

我的控制器如下所示:

public class SqlPlannerData : ISchoolPlannerData
    
        private readonly SchoolPlannerDbContext db;

        public SqlPlannerData(SchoolPlannerDbContext db)
        
            this.db = db;
        
        public IEnumerable<Activity> GetActivities()
        
            return db.Activities;
        
        public IEnumerable<Group> GetGroups()
        
            return db.Groups;            
        
   

GetGroups() 按预期工作并返回一个属性设置正确的 IEnumerable。

我的问题是,当我尝试访问 db.Activities 时,类型的属性,例如,Teacher(非基本类型,如 int)设置为 null: Debugger screenshot.

但是,数据库中有一行 looks like this。 IE。这些列存在于数据库中。

如何使 GetActivities() 返回具有正确设置属性的 IEnumerable?

【问题讨论】:

默认不加载相关实体。阅读:docs.microsoft.com/en-us/ef/core/querying/related-data db.Activities.Include(it =&gt; it.Teacher).Include(it =&gt; it.Room).ToListAsync() 等其他相关实体 1) When to use Include() with Entity Framework? 2) Why EF Async Methods are Slow 3) Entity Framework async operation takes ten times as long to complete @Jackdaw 两个链接似乎都很旧。我怀疑 EF Core 仍然会发生这种情况(慢速异步)。甚至可能是与 SqlServer 驱动程序相关的问题。 @abdusco:希望这个错误已经在 EF Core 中得到修复,或者可能没有。 【参考方案1】:

由于延迟加载,某些属性为空,您需要包含它们

    return db.Activities
             .Include(i => i.Teacher)
              .Include(i => i.Room)
            .Include(i => i.Subject)
              .Include(i => i.Group)
                   .ToList()

EF5+ 可以将每个属性 ID 配置为阴影。但我通常更喜欢明确添加所有 Id。这样,当我在项目中使用数据库上下文时,我的问题就会少得多。但 is 是可选的,您可以保持原样

public class Activity
    
        public int ID  get; set; 

        [Required]
        public int?  TeacherId  get; set; 

        [Required]
        public int? RoomId   get; set; 

        [Required]
        public  int? SubjectId  get; set; 

        [Required]
        public int? GroupId  get; set; 


        public virtual Teacher Teacher  get; set; 

       
        public virtual Room Room  get; set; 

     
        public virtual Subject Subject  get; set; 

       
        public  virtual Group Group  get; set; 

       
        [Required]
        public int Slot  get; set; 

        [Required]
        public int Day  get; set; 
    

为了获得列表活动,您必须至少添加 ToList() 或 ToArray()

 public IEnumerable<Activity> GetActivities()
        
            return db.Activities.ToArray();
        

顺便说一句,您不能按要求使用 not nullabe Id,因为它是相关的

 [Required]
 public int  TeacherId  get; set; 

因为 int 默认为 0,它是一个有效值,并且 required 将不起作用

【讨论】:

不是 OP 要求的。他/她问为什么有些属性是空的。 @abdusco 非常感谢!我更新了我的答案。 cmets /w 缺少急切加载已经涵盖了 OP 问题的答案。此答案中关于要求类定义中的 FK 的内容不正确且具有误导性。如果命名遵循公认的约定,EF 可以解析 FK。 (也不是我的一般建议,但它与 OP 面临的问题的根源无关) @StevePy 非常感谢您的建议。我很感激。我已经更新了我的答案。您再看一看,让我知道现在是否可以接受。

以上是关于类型类的 DbSet 属性返回 null的主要内容,如果未能解决你的问题,请参考以下文章

EF dbcontext 在 dynamo 自定义节点中返回一个空的 dbset

从类型中获取 DbSet

为啥基于类的视图返回类型对象'Profile'没有属性'model'?

EF DbSet.Find() 返回分离实体

使用返回类型声明返回 NULL

为啥我从 Dapper 返回的对象具有 null 和默认属性值?