Невозможно сохранить запись в базе данных с отображением 1: 1, используя EF Code First - PullRequest
0 голосов
/ 15 февраля 2019

В моем коде у меня есть 2 "таблицы", которые имеют отображение от 1 до 1 или от 1 до 0.Таблица person и таблица passport (я показываю код, который повторяет мою проблему, поэтому, пожалуйста, простите, насколько надуманы эти примеры).Это означает, что у человека может не быть паспорта, но у паспорта должен быть связанный человек.

Проблема, с которой я сталкиваюсь, заключается в том, что при сохранении я получаю следующее сообщение об ошибке

Aзависимое свойство в ReferentialConstraint отображается в столбец, созданный магазином.Колонка: «Id».

Должен признать, что на самом деле я не совсем понимаю проблему здесь!Да, я могу читать слова, но я не знаю, почему он борется со столбцом Id!

Это то, что у меня есть

[Table("Person")]
public partial class Person
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }

    public int PassportId {get;set;}

    public virtual Passport Passport {get;set;}
}

[Table("Passport")]
public partial class Passport 
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }

    public string PassportDetail { get; set; }

    public virtual Person Person { get; set; }
}

И в моих сущностях (DataContext) яhave

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{ 
    modelBuilder.Entity<Person>()              //create for person
            .HasOptional(a => a.Passport)      //a person has optional passport
            .WithRequired(s => s.Person);      //a passport requires a person
}

Сохранение в базе данных должно было быть простым ...

var p = new Person();
p.Passport = new Passport()
        {
              PassportDetail = "test"
        };
dataContext.Person.Add(p);
dataContext.SaveChanges();

Но меня предупредили по вышеуказанной причине.

Что я сделал не так?

Посты типа Зависимое свойство в ReferentialConstraint сопоставлено с генерируемым хранилищем столбцом кажется очень сложным и с плохо определенными таблицамигде, как я надеюсь (известные последние слова), моя ситуация проста, и я избежал этого)

Принятый ответ в Зависимое свойство в ReferentialConstraint сопоставлено с ошибкой столбца, сгенерированной хранилищем 1отношение * к-1 , кажется, показывает, что делает!

Исправление обновляется до

[Table("Passport")]
public partial class Passport 
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]  //changed here
    [Key]
    public int Id { get; set; }
….

Однако, если я делаю это, то когда я сохраняю свою базу данных, я 'мне говорят за вставку дубликатов :(

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

В действительности one-to-one отношения невозможны в sql server.Это могут быть one-to-zero-or-one отношения.В вашем случае один Person будет иметь единицу или ноль Passport, поэтому можно просто установить следующее соотношение, где Person в основном объекте и Passport является зависимым объектом.

[Table("Person")]
public partial class Person
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public PersonName {get;set;}

    public virtual Passport Passport {get;set;}
}

[Table("Passport")]
public partial class Passport 
{
    [Key,ForeignKey("Person")]
    public int PersonId { get; set; }  //<-- here `PersonId` the is both the Primary key and foreign key

    public string PassportDetail { get; set; }

    public virtual Person Person { get; set; }
}

Примечание: В этой настройке вам не нужна конфигурация Fluent API.

А при вставке:

var person = new Person()
{
    PersonName = "Test"
}

Passport passport = new Passport()
{
      PersonId = person.Id,
      PassportDetail = "test"
};

dataContext.Persons.Add(person);
dataContext.Passports.Add(passport);
dataContext.SaveChanges();
0 голосов
/ 15 февраля 2019

Я думаю, что быстрое исправление, которое вы нашли, не является правильным способом решения первой идеологии EF Code, чтобы иметь отношение один к одному, вы должны сопоставить каждую таблицу с первичным ключом другой таблицы, в вашем случаеэто int Id, но для человека, которому вы хотите, чтобы эта опция была необязательной, вы помечаете ее как обнуляемую, и EF сгенерирует правильные сценарии, позволяющие создавать Персона без Паспорта или с, и Паспорт разрешено создавать толькоесли есть связь с человеком

[Table("Person")]
public partial class Person
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }

    public int? PassportId {get;set;}

    public virtual Passport Passport {get;set;}
}

[Table("Passport")]
public partial class Passport 
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }

    public string PassportDetail { get; set; }

    public int PersonId {get;set;}

    public virtual Person Person { get; set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...