提问人:Nico1395 提问时间:8/18/2023 更新时间:8/19/2023 访问量:56
EF Core IEntityTypeConfigurations:从 DB 提取数据后,相关对象为 null
EF Core IEntityTypeConfigurations: Related object is null after drawing data from DB
问:
我正在使用 FluentMigrator 迁移进行数据访问设置。总的来说,我认为我对配置实体和表以建立关系有基本的了解,并且在某些时候它确实有效。IEntityTypeConfigurations
但是,现在我总是在从数据库中查询我想要的帐户时。我的角色的权限也会发生同样的情况。
在当前代码段之前,我已经拥有使用角色作为列表的帐户,并在这些帐户之间建立了关系,但这也不起作用。我有点困惑,老实说,在这一点上,我只是在没有任何理解的情况下尝试一些东西。UserAccounts
UserRole
null
据我所知,存储实体可以完美地工作,就像我想要的那样。在将上下文中的更改保存到数据库后,这些实体完全处于我希望它们处于的状态。这意味着所有权限都存在于我的角色中,并且该角色存在于我的帐户中,其中包含我想要的所有数据。
public class UserAccount
{
public int Id { get; set; }
public string Email { get; set; } = string.Empty;
public string PhoneNumber { get; set; } = string.Empty;
public string LoginName { get; set; } = string.Empty;
public string PasswordHash { get; set; } = string.Empty;
public DateTime PasswordChanged { get; set; } = DateTime.Now;
public int RoleId? { get; set; }
public virtual UserRole? Role { get; set; }
}
public class UserAccountEntityMap : IEntityTypeConfiguration<UserAccount>
{
public void Configure(EntityTypeBuilder<UserAccount> builder)
{
builder.ToTable("UserAccounts");
builder.HasKey(x => x.Id);
builder.Property(u => u.Id).HasColumnName("Id").UseIdentityColumn();
builder.Property(u => u.Email).HasColumnName("Email");
builder.Property(u => u.PhoneNumber).HasColumnName("PhoneNumber");
builder.Property(u => u.LoginName).HasColumnName("LoginName");
builder.Property(u => u.PasswordHash).HasColumnName("PasswordHash");
builder.Property(u => u.PasswordChanged).HasColumnName("PasswordChanged");
builder.HasOne(u => u.Role)
.WithMany()
.HasForeignKey(u => u.RoleId);
}
}
// Migration creating the table
public override void Up()
{
if (!Schema.Table("UserAccounts").Exists())
{
Create.Table("UserAccounts")
.WithColumn("Id")
.AsInt32()
.NotNullable()
.PrimaryKey()
.Identity()
.WithColumn("Email")
.AsString()
.WithColumn("PhoneNumber")
.AsString()
.WithColumn("LoginName")
.AsString()
.WithColumn("PasswordHash")
.AsString()
.WithColumn("PasswordChanged")
.AsDateTime2()
.WithColumn("RoleId")
.AsInt32()
.ForeignKey();
Create.ForeignKey("FK_UserAccount_UserRole")
.FromTable("UserAccounts")
.ForeignColumn("RoleId")
.ToTable("UserRoles")
.PrimaryColumn("Id");
}
}
public class UserRole
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public DateTime LastChanged { get; set; } = DateTime.Now;
public virtual List<UserRolePermission> Permissions { get; set; } = new();
}
public class UserRoleEntityMap : IEntityTypeConfiguration<UserRole>
{
public void Configure(EntityTypeBuilder<UserRole> builder)
{
builder.ToTable("UserRoles");
builder.HasKey(t => t.Id);
builder.Property(r => r.Id).HasColumnName("Id").UseIdentityColumn();
builder.Property(r => r.Name).HasColumnName("Name");
builder.Property(r => r.Description).HasColumnName("Description");
builder.Property(r => r.LastChanged).HasColumnName("LastChanged");
builder.HasMany(r => r.Permissions)
.WithOne()
.HasForeignKey(p => p.RoleId);
}
}
// Migration creating the table
public override void Up()
{
if (!Schema.Table("UserRoles").Exists())
{
Create.Table("UserRoles")
.WithColumn("Id")
.AsInt32()
.NotNullable()
.PrimaryKey()
.Identity()
.WithColumn("Name")
.AsString()
.WithColumn("Description")
.AsString()
.WithColumn("LastChanged")
.AsDateTime2();
}
}
我尝试了很多东西,甚至参考了我们在工作中使用的配置,我正在做学徒 - 我的设置几乎是镜像它 - 但我就是无法让它工作。
我试图使我的相关属性虚拟,但没有成功,我在新数据库上多次更改了迁移和实体配置。网上很多资源只引用和呈现自动生成的模型配置和迁移,即使是那些没有的资源,似乎也没有给我带来任何进一步的帮助。
所以我有几个具体的问题
外键几乎是描述与数据库对象相关的表和列的“引用”。多列可以组成一个外键。我的观点是对的,还是我误解了我迄今为止收集的信息?
主键几乎是标识器,显然是唯一的,可以由多个列组成,这些列是唯一描述数据库条目所必需的。我说得对吗?
可以在没有密钥的情况下在实体配置中设置实体,有哪些用例?
显然:我在上面的尝试中有什么问题?我不明白什么,我需要调整什么?
答:
你在做延迟加载吗?试试这个
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString);
https://learn.microsoft.com/en-us/ef/core/querying/related-data/lazy
评论
UserAccount
Role