类型类的 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-datadb.Activities.Include(it => it.Teacher).Include(it => 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