Настроить отношение один к одному в структуре сущности? [Дубликат]

Это одно из самых запутанных сообщений об ошибках, которые каждый программист VC ++ видел снова и снова. Давайте сначала сделаем чёткость.

A. Что такое символ? Короче говоря, символ - это имя. Это может быть имя переменной, имя функции, имя класса, имя typedef или что-либо кроме тех имен и знаков, которые принадлежат языку C ++. Он определяется пользователем или вводится библиотекой зависимостей (другой пользовательский).

B. Что является внешним? В VC ++ каждый исходный файл (.cpp, .c и т. Д.) Рассматривается как единица перевода, компилятор компилирует по одному модулю за раз и генерирует один объектный файл (.obj) для текущей единицы перевода. (Обратите внимание, что каждый заголовочный файл, включенный в этот исходный файл, будет предварительно обработан и будет рассматриваться как часть этой единицы перевода). Все внутри единицы перевода считается внутренним, все остальное считается внешним. В C ++ вы можете ссылаться на внешний символ, используя ключевые слова, такие как extern, __declspec (dllimport) и т. Д.

C. Что такое «решимость»? Resolve - термин времени связывания. Во время компоновки линкер пытается найти внешнее определение для каждого символа в объектных файлах, которые не могут найти свое определение внутри. Объем этого процесса поиска, включая:

  • Все объектные файлы, сгенерированные во время компиляции
  • Все библиотеки (.lib), которые явно или неявно указаны как дополнительные зависимости это строительное приложение.

Этот процесс поиска называется разрешением.

D. Наконец, почему Unresolved External Symbol? Если компоновщик не может найти внешнее определение для символа, который не имеет определения внутри, он сообщает об ошибке неразрешенного внешнего символа.

E. Возможные причины LNK2019: ошибка неразрешенного внешнего символа. Мы уже знаем, что эта ошибка связана с тем, что компоновщик не смог найти определение внешних символов, возможные причины могут быть отсортированы как:

  1. Определение существует

Например, если у нас есть функция foo, определенная в a.cpp:

int foo()
{
    return 0;
}

В b.cpp мы хотим вызвать функцию foo, поэтому добавим

void foo();

, чтобы объявить функцию foo () и вызвать ее в другом теле функции, скажем bar():

void bar()
{
    foo();
}

Теперь, когда вы создаете этот код, вы получите ошибку LNK2019, жалуясь, что foo является неразрешенным символом , В этом случае мы знаем, что foo () имеет свое определение в a.cpp, но отличается от того, которое мы вызываем (другое возвращаемое значение). Это означает, что определение существует.

  1. Определение не существует

Если мы хотим вызвать некоторые функции в библиотеке, но библиотека импорта не добавлен в дополнительный список зависимостей (установленный из: Project | Properties | Configuration Properties | Linker | Input | Additional Dependency) вашего проекта. Теперь компоновщик сообщит LNK2019, поскольку определение не существует в текущей области поиска.

244
задан Luke Sampson 3 February 2014 в 11:53
поделиться

3 ответа

В отношениях один к одному один конец должен быть основным, а второй конец должен быть зависимым. Основной конец - тот, который будет вставлен первым и который может существовать без зависимого. Зависимый конец - тот, который должен быть вставлен после принципала, потому что у него есть внешний ключ для принципала.

В случае фреймворка сущности FK в зависимом случае также должен быть его PK, поэтому в вашем случае вы должны использовать:

public class Boo
{
    [Key, ForeignKey("Foo")]
    public string BooId{get;set;}
    public Foo Foo{get;set;}
}

Или плавное отображение

modelBuilder.Entity<Foo>()
            .HasOptional(f => f.Boo)
            .WithRequired(s => s.Foo);
349
ответ дан Ladislav Mrnka 1 September 2018 в 06:31
поделиться

Вы также можете использовать атрибут аннотации данных [Required] для этого:

public class Foo
{
    public string FooId { get; set; }

    public Boo Boo { get; set; }
}

public class Boo
{
    public string BooId { get; set; }

    [Required]
    public Foo Foo {get; set; }
}

Foo требуется для Boo.

166
ответ дан Leniel Maccaferri 1 September 2018 в 06:31
поделиться

Это касается ответа @Ladislav Mrnka на использование свободного api для настройки отношения «один к одному».

Если бы ситуация, когда FK of dependent must be it's PK была невозможна.

Например, Foo уже имеет отношение «один ко многим» с Bar.

public class Foo {
   public Guid FooId;
   public virtual ICollection<> Bars; 
}
public class Bar {
   //PK
   public Guid BarId;
   //FK to Foo
   public Guid FooId;
   public virtual Foo Foo;
}

Теперь нам пришлось добавить еще одну взаимно-однозначную связь между Foo и Bar.

public class Foo {
   public Guid FooId;
   public Guid PrimaryBarId;// needs to be removed(from entity),as we specify it in fluent api
   public virtual Bar PrimaryBar;
   public virtual ICollection<> Bars;
}
public class Bar {
   public Guid BarId;
   public Guid FooId;
   public virtual Foo PrimaryBarOfFoo;
   public virtual Foo Foo;
}

Вот как указать отношения «один-к-одному», используя беглый api:

modelBuilder.Entity<Bar>()
            .HasOptional(p => p.PrimaryBarOfFoo)
            .WithOptionalPrincipal(o => o.PrimaryBar)
            .Map(x => x.MapKey("PrimaryBarId"));

. Обратите внимание, что при добавлении PrimaryBarId необходимо удалить, поскольку мы определяем его с помощью свободного api.

Также обратите внимание, что имя метода [WithOptionalPrincipal()][1] является своеобразным ироничным. В этом случае Principal Bar. Описание WithOptionalDependent () в msdn делает его более понятным.

4
ответ дан Patrick 1 September 2018 в 06:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: