簡體   English   中英

實體框架“包含”不加載實體相關表

[英]Entity Framework “Include” does not load entity related tables

我有一個使用 Visual Studio 2019(64 位)和 SQL Server 2019 的 ASP.NET Core 3.1 項目。當我運行后端時,當我使用 Entity Framework 的.Include從相關表加載數據時,它會生成錯誤。 奇怪的是,相同的代碼在 Visual Studio 2017 中使用 ASP.NET Core 2.1 沒有問題。在我使用.Include從相關表加載數據的每種方法中都會發生這種情況。

下圖顯示了我運行后端時產生的錯誤:

在此處輸入圖片說明

這是我使用.Include的方法:

namespace Sistema.Web.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ArticulosController : ControllerBase
    {
        private readonly DbContextSistema _context;

        public object Articulos { get; private set; }

        public ArticulosController(DbContextSistema context)
        {
            _context = context;
        }

        [HttpGet("[action]")]
        public async Task<IEnumerable<ArticuloViewModel>> Listar()
        {
            var articulo = await _context.Articulos.Include(a=>a.categoria).ToListAsync();
            return articulo.Select(a => new ArticuloViewModel
            {
                idarticulo = a.idarticulo,
                idcategoria = a.idcategoria,
                categoria = a.categoria.nombre,
                codigo = a.codigo,
                nombre = a.nombre,
                stock = a.stock,
                precio_venta = a.precio_venta,
                descripcion = a.descripcion,
                condicion = a.condicion
            });
        }

        private bool ArticuloExists(int id)
        {
            return _context.Articulos.Any(e => e.idarticulo == id);
        }
    }
}

這是主表(Articulo)的實體:

namespace Sistema.Entidades.Almacen
{
    public class Articulo
    {
        public int idarticulo { get; set; }
        [Required]
        public int idcategoria { get; set; }
        public string codigo { get; set; }
        [Required]
        public string nombre { get; set; }
        [Required]
        public decimal precio_venta { get; set; }
        [Required]
        public int stock { get; set; }
        [StringLength(256)]
        public string descripcion { get; set; }
        public bool condicion { get; set; }

        public Categoria categoria { get; set; }
    }
}

這是相關表(類別)的實體:

namespace Sistema.Entidades.Almacen
{
    public class Categoria
    {
        public int idcategoria { get; set; }
        [Required]
        public string nombre { get; set; }
        [StringLength(256)]
        public string descripcion { get; set; }
        public bool condicion { get; set; }

        public ICollection<Articulo> articulos { get; set; }
    }
}

這是Articulo的映射類:

namespace Sistema.Datos.Mapping.Almacen
{
    public class ArticuloMap : IEntityTypeConfiguration<Articulo>
    {
        public void Configure(EntityTypeBuilder<Articulo> builder)
        {
            builder.ToTable("articulo")
                .HasKey(a => a.idarticulo);     
        }
    }
}

這是Categoria的映射類:

namespace Sistema.Datos.Mapping.Almacen
{
    public class CategoriaMap : IEntityTypeConfiguration<Categoria>
    {
        public void Configure(EntityTypeBuilder<Categoria> builder)
        {
            builder.ToTable("categoria")
                .HasKey(c => c.idcategoria);
            builder.Property(c => c.nombre)
                .HasMaxLength(50);
            builder.Property(c => c.descripcion)
                .HasMaxLength(256);
        }
    }
}

這是我包含ArticuloMapCategoriaMapDbContext

namespace Sistema.Datos
{
    public class DbContextSistema : DbContext
    {
        public DbSet<Categoria> Categorias { get; set; }
        public DbSet<Articulo> Articulos { get; set; }
        public DbSet<Rol> Roles { get; set; }
        public DbSet<Usuario> Usuarios { get; set; }
        public DbSet<Persona> Personas { get; set; }
        public DbSet<Ingreso> Ingresos { get; set; }

        public object Entry(object articulos)
        {
            throw new NotImplementedException();
        }

        public DbSet<DetalleIngreso> DetalleIngresos { get; set; }
        public DbSet<Venta> Ventas { get; set; }
        public DbSet<DetalleVenta> DetalleVentas { get; set; }

        public DbContextSistema(DbContextOptions<DbContextSistema> options) : base(options)
        {

        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            
            modelBuilder.ApplyConfiguration(new CategoriaMap());
            modelBuilder.ApplyConfiguration(new ArticuloMap());
            modelBuilder.ApplyConfiguration(new RolMap());
            modelBuilder.ApplyConfiguration(new UsuarioMap());
            modelBuilder.ApplyConfiguration(new PersonaMap());
            modelBuilder.ApplyConfiguration(new IngresoMap());
            modelBuilder.ApplyConfiguration(new DetalleIngresoMap());
            modelBuilder.ApplyConfiguration(new VentaMap());
            modelBuilder.ApplyConfiguration(new DetalleVentaMap());
        }
    }
}

這是articulocategoria的 db 表設計以及請求的 db 關系:

在此處輸入圖片說明

.NET Core 3.1 有什么變化嗎? 我是否需要更改或調整以解決此問題? 非常感謝您的回復!

編輯:

  • 替換了源代碼的圖像。
  • 添加了相關表Categoria的實體的源代碼。
  • 添加了映射類CategoriaMap源代碼。
  • 添加了 db 表設計和關系的圖像。

我提前為僅使用圖像而不是源代碼發布帖子而道歉。 感謝您的回復,我希望最后一次編輯使問題的解決方案更加清晰。

有幾種方法可以告訴 EF 如何建立關系。 默認情況下,您的對象:

//principal
public class Categoria
{
    public int idcategoria { get; set; }

    ...

    public ICollection<Articulo> articulos { get; set; }
}

//dependent
public class Articulo
{
    public int idarticulo { get; set; }
    public int idcategoria { get; set; }

    ...

    public Categoria categoria { get; set; }
}

EF 將能夠看到這些是相關的,因為一個 Articulo 有一個 Categoria,而一個 Categoria 有許多 Articulo,因此它可以推斷出 1:M 關系的結構。 在猜測到主體的從屬鏈接的哪一列時,它會嘗試:

  • 類別idcategoria(斜體 -> 依賴導航屬性名稱)
  • 類別ID
  • 類別idcategoria(斜體 -> 主要類名)
  • 類別ID

最關鍵的是,它不再(自 3.0 起)嘗試在具有相同名稱的兩個類之間找到一對屬性,我認為這就是它以前工作的原因


如果您的命名約定是典型的英語,它會找到它,但根據這些規則,它不會找到西班牙風格的名稱,因此您必須明確,可能最簡單的方法是注釋關系中的任何一個屬性(EF 不不在乎哪個) - 我認為任何一種方式都是可以接受的:

  • 如果您在依賴項中執行此操作,那么您將引用同一類中的屬性,因此您不必查看另一個類/打開另一個文件來檢查它所指的內容
  • 如果您在主要做到這一點,那么你如何描述這類鏈接的那個類的什么屬性的屬性

所以它看起來像:

//principal
public class Categoria
{
    public int idcategoria { get; set; }

    ...

    [ForeignKey("idcategoria")] //it means Articulo.idcategoria is the relevant property that links to PK of this class
    public ICollection<Articulo> articulos { get; set; }
}

或者

//dependent
public class Articulo
{
    public int idarticulo { get; set; }
    public int idcategoria { get; set; }

    ...

    [ForeignKey("idcategoria")] //it means idcategoria proerty above is the relevant property that links to PK property of Categoria
    public Categoria categoria { get; set; }
}

我想只要選擇你更喜歡的那個並保持一致。 MSDN 中的示例使用依賴

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM