EF Core IEntityTypeConfigurations:从数据库提取数据后相关对象为空

问题描述 投票:0回答:1

我正在使用

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();
    }
}

我尝试了很多东西,甚至参考了我们在工作中使用的配置,我正在那里做学徒 - 我的设置几乎镜像它 - 但我就是无法让它工作。

我尝试将相关属性虚拟化,但没有成功,我在新数据库上多次更改了迁移和实体配置。很多在线资源仅参考并呈现自动生成的模型配置和迁移,甚至那些没有的资源似乎也没有给我带来任何进一步的帮助。

所以我有几个具体问题

  • 外键几乎是描述与数据库对象相关的表和列的“引用”。多个列可以形成外键。我的说法是对的还是我误解了迄今为止收集到的信息?

  • 主键几乎是标识符,显然是唯一的,并且可以由唯一描述数据库条目所需的多个列组成。我说得对吗?

  • 可以在没有密钥的情况下在实体配置中设置实体,有哪些用例?

  • 显然:我在上述尝试中遇到的问题是什么?我哪些不明白,哪些需要调整?

.net database entity-framework entity-framework-core fluent-migrator
1个回答
0
投票

你在做延迟加载吗?试试这个

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseLazyLoadingProxies()
        .UseSqlServer(myConnectionString);

https://learn.microsoft.com/en-us/ef/core/querying/lated-data/lazy

© www.soinside.com 2019 - 2024. All rights reserved.