Сначала код EF Core — взаимосвязь уже используется

avatar
wwdev
8 августа 2021 в 16:45
121
0
0

Я все еще новичок в .NET, особенно в ядре ef. У меня возникли проблемы с определением отношений между сущностями, использующими первый подход к коду с существующей базой данных. Я разрабатываю это с помощью кода Visual Studio, и я не могу использовать первый подход к модели. У меня есть 2 таблицы с отношением 1:1. Чтобы получить приведенную ниже структуру json, я создал 3 объекта (где 1 объект необходимо разделить). На основе отношения, которое я определил, он жалуется на то, что сущность уже используется. Может ли кто-нибудь указать мне, что я делаю неправильно при определении отношений?

Я получил следующую ошибку:

System.InvalidOperationException: нельзя использовать таблицу 'dbo.unitDetailTbl' для типа сущности "контакт", так как она используется для типа сущности "адрес" и, возможно, других типов сущностей, но нет связывающей связи. Добавьте внешний ключ, чтобы «контактировать» в свойствах первичного ключа и указывающий на первичный ключ в другом типе объекта, сопоставленном с «dbo.unitDetailTbl».

Структура таблиц (связь 1 к 1)

  • unitInfoTbl (unitId, имя)
  • unitDetailTbl (unitId, addr1, phone)
CREATE TABLE [dbo].[unitDetailTbl](
    [UnitId] [int] NOT NULL Primary Key,
    [Addr1] [varchar](250) NULL,
    [Phone][varchar](32) NULL,
    
)

GO

CREATE TABLE [dbo].[unitInfoTbl](
    [UnitId] [int] NOT NULL Primary Key,
    [Name] [varchar](250) NULL,
    Foreign Key (UnitId) REFERENCES [unitDetailTbl](UnitId)
)
GO

INSERT INTO dbo.unitDetailTbl VALUES (1,'123 East Madison','123-456-7891');
INSERT INTO dbo.unitInfoTbl VALUES (1,'Building');

GO

Ожидаемый результат

[
  {
    "unitId": 1,
    "name": "Building",
    "address": {
      "unitId": 1,
      "addr1": "123 East Madison"
    },
    "contact": {
      "unitId": 1,
      "phone": "123-456-7891"
    }
  }
]

Модели

public partial class unitInfo
    {
        [Key]

        public int UnitId { get; set; }
        public string name { get; set; }

        public virtual address address { get; set;} 

        public virtual contact contact { get; set;} 
    }

public partial class contact
    {
        [Key,JsonIgnore]
        public int UnitId { get; set; }

        public string phone {get; set;}        
        
        public virtual unitInfo unitInfoContact {get;set;} 
    }
    
public partial class address
    {
        
        [Key,JsonIgnore]
        public int UnitId { get; set; }

        public string Addr1 {get; set;}
    
        public virtual unitInfo unitInfoAddress { get; set; } 
        
    }

Контекст

public partial class unitInfoContext : DbContext
    {
         public unitInfoContext()
        {
        }

         public unitInfoContext(DbContextOptions<unitInfoContext> options)
            : base(options)
        {
        }

        public virtual DbSet <unitInfo> getUnitInfo {get; set;}
        public virtual DbSet <address> getAddress {get; set;}
        public virtual DbSet <contact> getPhone {get; set;}


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<unitInfo>(entity =>
            {
                entity.ToTable("unitInfoTbl", "dbo");
                        
                entity.HasOne(d => d.address)
                    .WithOne(a=>a.unitInfoAddress)
                    .HasForeignKey<unitInfo>(d => d.UnitId);

                entity.HasOne(c => c.contact)
                    .WithOne(a => a.unitInfoContact)
                    .HasForeignKey<unitInfo>(d => d.UnitId);
                 
            });
            
            //The address and contact entities are using the same table            
           modelBuilder.Entity<address>(entity =>
            {
                entity.ToTable("unitDetailTbl", "dbo");

            });

            modelBuilder.Entity<contact>(entity =>
            {
                entity.ToTable("unitDetailTbl", "dbo");
                 
            });

        }
    }

Я попытался создать еще одно свойство в AddressId, которое действует как FK, и сопоставил его в контексте с unitId. Это все еще не сработало, потому что в базе данных ожидается unitId1. Я чувствую, что смешал в модели и аннотацию, и Fluent API.

Другое дело, я пытаюсь скрыть свойство unitId в адресе и объектах контакта, используя следующие аннотации, но ни одна из них не работает:

  • [JsonIgnore]
  • [ScaffoldColumn(false)]
  • [Display(AutoGenerateField=false)]
Источник
David Browne - Microsoft
8 августа 2021 в 16:52
1

Что такое схема «существующей базы данных»? Вы пытались реконструировать модель объекта из базы данных, согласно docs.microsoft.com/en-us/ef/ef6/modeling/code-first/workflows/…?

Gert Arnold
8 августа 2021 в 17:26
0

Это не EF6, укажите правильную версию.

Gert Arnold
8 августа 2021 в 17:37
0

Сейчас нет версии. Для вопросов EF очень важно указывать точную версию. Что касается модели, если есть одна таблица unitDetailTbl, в чем причина сопоставления с ней двух классов? Обратите внимание, что для этого требуется специальное сопоставление: docs.microsoft.com/en-us/ef/core/modeling/….

wwdev
8 августа 2021 в 18:56
0

@Gert, TargetFramework имеет чистую версию 5.0, а версия ссылок пакета на Microsoft.EntityFrameworkCore - 5.0.8. Я прочитаю, что требуется конкретное сопоставление. Причина сопоставления двух классов, чтобы объекты адреса и контакта могли быть на одном уровне во вложенном json, как вы видите в ожидаемом результате. Если я использую только 1 класс, это будет Ex: `[ { "unitId": 1, "name": "Building", "address": { "unitId": 1, "addr1": "123 East Madison", "телефон": "123-456-7891" }, } ] `

wwdev
8 августа 2021 в 19:02
0

@David, я включил часть кода базы данных выше. Я загрузил VS 2019 Community и использовал модель объекта с помощью шаблона веб-приложения ASP.NET, чтобы получить доступ к модели данных объекта ADO.Net с помощью .NET Framework 4.7.2. Code First From Database генерирует следующее `modelBuilder.Entity<unitDetailTbl>() .HasOptional(e => e.unitInfoTbl) .WithRequired(e => e.unitDetailTbl); ` Я еще не смог запустить код. Прошу прощения, у меня нет четкого понимания технологий .NET. Я все еще пытаюсь догнать терминологию и понятия.

Ответы (0)