我正在使用
IEntityTypeConfigurations
和 FluentMigrator 迁移进行数据访问设置。一般来说,我认为我对配置实体和表以解决关系有基本的了解,并且在某些时候它确实起作用了。
但是现在从数据库查询我想要的帐户时,我的
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/lated-data/lazy