EF Core外键不能与现有数据库一起使用

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

我正在构建一个使用现有MS SQL数据库的.NET Core MVC应用程序。主键和外键已经建立并在数据库级别正常工作。

我按照this article中的示例进行操作,并使用包管理器控制台对数据库中的模型和数据库上下文进行反向工程。这看起来效果很好。这导致所有模型被添加到我的应用程序的Models文件夹中,包括一个强大的数据库上下文类。我遇到的问题是关于这些实体的关系信息没有在运行时填充。我为相关实体获取空值,在数据库和脚手架流程生成的流畅API代码中都建立了外键。

我有两个表,模式和子模式,通过外键相关。

脚手架为上面两个表生成了这两个类:

public partial class Submode
{
    public Submode()
    {
        Contact = new HashSet<Contact>();
    }

    public int Id { get; set; }
    public int ModeId { get; set; }
    public string Code { get; set; }
    public bool Visible { get; set; }
    public bool IsDefault { get; set; }

    public Mode Mode { get; set; }
    public ICollection<Contact> Contact { get; set; }
}

public partial class Mode
{
    public Mode()
    {
        Contact = new HashSet<Contact>();
        Submode = new HashSet<Submode>();
    }

    public int Id { get; set; }
    public string Code { get; set; }
    public bool Visible { get; set; }
    public bool IsDefault { get; set; }

    public ICollection<Contact> Contact { get; set; }
    public ICollection<Submode> Submode { get; set; }
}

Scaffolding还在数据库上下文中生成了这个流畅的API代码段:

            modelBuilder.Entity<Submode>(entity =>
        {
            entity.HasIndex(e => e.Code)
                .HasName("UQ__Submode__A25C5AA75D2A9AE7")
                .IsUnique();

            entity.Property(e => e.Code)
                .IsRequired()
                .HasMaxLength(100)
                .IsUnicode(false);

            entity.HasOne(d => d.Mode)
                .WithMany(p => p.Submode)
                .HasForeignKey(d => d.ModeId)
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK_Submode_ModeId");
        });

我读过的关于使用流畅API设置外键的每个示例都显示了与上述代码段相似的模式。但是模式为Submode返回null。

Null at runtime

我在返回的视图中得到一个空引用异常,因为我试图显示相关Mode对象的属性。我错过了一些配置或脚手架代码有问题吗?

UDPATE - 根据要求,这是从数据库上下文中获取数据的实现。

public class SQLSubModeData : ISubModeData
{
    private w4lkrContext _context;

    public SQLSubModeData(w4lkrContext context)
    {
        _context = context;
    }

    public IQueryable<Submode> Get()
    {
        return _context.Submode.OrderBy(p => p.Id);
    }

    public Submode Get(int id)
    {
        return _context.Submode.FirstOrDefault(p => p.Id == id);
    }
}

更新(求助) - 启用延迟加载修复了问题。三个步骤让我在那里:

  1. 通过NuGet安装Microsoft.EntityFrameworkCore.Proxies(2.1.2)
  2. 更新了Startup.cs - > AddDbContext()方法,如下所示: services.AddDbContext(options => options.UseLazyLoadingProxies()。UseSqlServer(_configuration.GetConnectionString(“W4LKR”)));
  3. 使所有导航属性虚拟化。这必须在应用程序中的每个模型上完成,而不仅仅是在上面的示例中调用的模型。如果遗漏一个错误,就会抛出错误。
database entity-framework loading lazy-evaluation core
1个回答
1
投票

但是模式为Submode返回null。

由于您的导航属性未声明为virtual,因此您已禁用延迟加载,因此如果您执行Eager Loading或显式加载,EF将仅填充您的导航属性。

Loading Related Data

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