Неизвестный столбец ‘a.addresscod_address’ в ‘списке полей — C#

#c# #mysql #asp.net-mvc

#c# #mysql #asp.net-mvc

Вопрос:

Друзья, в нем была таблица «person», в которую записывалась информация пользователя. Теперь я создал таблицу «address» для хранения адресной информации пользователя.

Теперь мне нужно реорганизовать свой код, потому что у меня проблемы с отношениями. Это мои файлы:

Person.cs

 using LojaVirtual.Libraries.Lang;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace LojaVirtual.Models
{
    public class person
    {
        /* PK */
        [Key]
        public int cod_person { get; set; }

        public string name { get; set; }
        public DateTime date { get; set; }
        public string gender{ get; set; }
        .
        .
        public string email { get; set; }
        public string password { get; set; }
        public addres addres { get; set; }
        
        [ForeignKey("cod_person")]
        public virtual ICollection<order> Order { get; set; }
    }
}

 

Address.cs

 using System;
using System.Collections.Generic;
using LojaVirtual.Libraries.Lang;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace LojaVirtual.Models
{
    public class address
    {
        [Key]
        public int cod_address{ get; set; }

        public string { get; set; }
        public string neighborhood{ get; set; }

        public string city { get; set; }
        public string state{ get; set; }
        .
        .

        [ForeignKey("person")]
        public int? cod_person { get; set; }

        public person person { get; set; }
    }
}

 

LojaVirtualContext.cs

 
using LojaVirtual.Models;
using LojaVirtual.Models.ProdutoAgregador;
using Pomelo.EntityFrameworkCore.MySql;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;


namespace LojaVirtual.Database
{
    public class LojaVirtualContext : DbContext
    {
        /*
         * EF Core - ORM
         * ORM -> Bibliteca mapear Objetos para Banco de Dados Relacionais
         */
        public LojaVirtualContext(DbContextOptions<LojaVirtualContext> options) : base(options)
        {

        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<person>()
                .HasOne<address>(s => s.address)
                .WithOne(ad => ad.person)
                .HasForeignKey<address>(ad => ad.cod_person);

        }
        public DbSet<person> person { get; set; }
        public DbSet<order> order{ get; set; }
        public DbSet<address> addres { get; set; }
    }
}
 

Здесь, в этой строке, я получаю ошибку, которую я не могу решить:

 public List<order> ObterTodosPedidosPorSituacao(string status)
{
 return _banco.order
       .Include(a => a.order_situation)
       .Include(a => a.person)
       .ThenInclude(p => p.address)
       .Where(a => a.Situation == status).ToList();}
 

Мне нужно получить доступ к полям таблицы адресов через таблицу person. Я считаю, что это все, но я получаю сообщение об ошибке:

MySQL.Data.MySqlClient.Исключение MySqlException: ‘Неизвестный столбец ‘a.addresscod_address’ в ‘списке полей»

Я также пробовал: a.person.address, но возникает та же ошибка.

Я признателен, если кто-нибудь сможет проанализировать.

Комментарии:

1. Что такое _banco? Не могли бы вы, пожалуйста, включить полный код, включая конструктор?

Ответ №1:

Здесь у вас неправильная настройка отношений

 modelBuilder.Entity<person>()
    .HasOne<address>(s => s.address)
    .WithOne(ad => ad.person)
    .HasForeignKey<person>(ad => ad.cod_person); // <-- problem: ad is person
 

Тип ad в последней строке — это тип аргумента HasForeignKey универсального типа. Вы должны прочитать это так — аргумент универсального типа HasForeignKey — это тип объекта, содержащий внешний ключ.

Итак, что вы здесь делаете, это, по сути, настройка PK person объекта, который будет использоваться также как FK для address , что делает недействительным предполагаемый FK в address (поскольку свободная конфигурация имеет более высокий приоритет / переопределяет соглашения и аннотации данных).

С учетом сказанного, просто сопоставьте address зависимый объект as отношения «один к одному» (объект с FK), изменив аргумент универсального типа:

 .HasForeignKey<address>(ad => ad.cod_person);
 

Также рассмотрите возможность удаления (и вообще избегания) ForeignKey атрибутов. Они имеют разную семантику в зависимости от применяемого места (в свойстве навигации указывается имя связанного свойства FK, а в свойстве FK указывается имя связанного свойства навигации) и могут быть легко перепутаны, как в вашем случае:

 [ForeignKey("cod_person")] // <-- wrong, points to self
public int? cod_person { get; set; }
public person person { get; set; }
 

Это должно быть либо

 [ForeignKey("person")] // the name of the below navigation property
public int? cod_person { get; set; }
public person person { get; set; }
 

или

 public int? cod_person { get; set; }
[ForeignKey("cod_person")] // the name of the above FK property
public person person { get; set; }
 

но, как я уже говорил ранее, лучше избегать использования этого атрибута и настраивать отношения с fluent API, где это необходимо.

Комментарии:

1. Спасибо за отзыв. Я обновил код, получил следующее: MySQL.Data.MySqlClient. Исключение MySqlException: ‘Неизвестный столбец ‘a.addresscod_address’ в ‘списке полей»

2. Теперь я получаю этот результат: ‘Свойство или навигация ‘person’ не могут быть добавлены к типу объекта ‘address’, потому что свойство или навигация с тем же именем уже существуют для типа объекта ‘address

Ответ №2:

Это должно сработать:

 public List<order> ObterTodosPedidosPorSituacao(string status)
{
    return _banco.order
       .Include(a => a.order_situation)
       .Include(a => a.person)
       .ThenInclude(p => p.address)
       .Where(a => a.Situation == status).ToList();
}
 

Но я только предполагаю, потому что включен не весь код. Если бы я мог что-то предложить — в c # существует строгое соглашение об именах. Это не имеет большого значения, но помогает работать в командах :).

редактировать: я видел другую проблему с аннотацией данных. [ForeignKey("cod_person")] -это избыточно. Не забудьте выполнить миграцию БД после внесения изменений.

Комментарии:

1. Спасибо за отзыв. Я обновил код, получил следующее: MySQL.Data.MySqlClient. Исключение MySqlException: ‘Неизвестный столбец ‘a.addresscod_address’ в ‘списке полей»

2. Теперь я получаю этот результат: ‘Свойство или навигация ‘person’ не могут быть добавлены к объекту типа ‘address’, потому что свойство или навигация с тем же именем уже существуют для объекта типа ‘address’. ‘