Отсутствует идентификатор при вставке от одного к одному или нулю с Entity Framework - PullRequest
0 голосов
/ 23 мая 2018

Используя EF6 для сервера SQL, при сохранении записи с отношением один к нулю или единице необходимо настроить сопоставления для того, чтобы идентификатор «Один» был установлен в «ноль».-or-one "

Простым случаем для этого может быть:

public class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
    public virtual Car Car { get; set; }
}

public class Car
{
    public int CarId { get; set; }
    public string Make { get; set; }
    public int? PersonId { get; set; }
    public virtual Person Person { get; set; }
}

С конфигурациями сопоставления

public class PersonMap : EntityTypeConfiguration<Person>
{
    public PersonMap()
    {
        HasKey(x => x.PersonId);
        HasOptional(x => x.Car)
            .WithRequired(x => x.Person);
    }
}

public class CarMap : EntityTypeConfiguration<Car>
{
    public CarMap()
    {
        HasKey(x => x.CarId);
        Property(x => x.Make).IsRequired();
        HasRequired(x => x.Person)
            .WithOptional(x => x.Car);
    }
}

Выполнение очень простого теста на любые измененияПриведенные выше сопоставления всегда приводят к тому, что объект Car имеет PersonId из null

[TestFixture]
public class PersonMappingTest
{
    [Test]
    public void ItWorks()
    {
        var person = new Person {Name = "Test person"};
        var car = new Car {Person = person, Make = "Ford"};
        person.Car = car;
        car.Person = person;

        using (var cx = new CompWalkContext())
        {
            cx.Persons.Add(person);
            cx.SaveChanges();
        }

    }
}

-

CarId   Make    PersonId
-----   ----    --------
1       Ford    NULL
2       Ford    NULL

Возможно ли это, или для этого необходим объект Personбыть сохраненным до добавления Car?

1 Ответ

0 голосов
/ 24 мая 2018

Вам не нужно двойное сопоставление, и ваши ключи немного перегорели.Автомобилю нужен человек, поэтому PersonID не может быть обнуляемым, если у человека может быть, а может и нет автомобиль.если вы хотите PersonId на машине, это 1-0..1 между человеком и машиной.Отсюда вы устанавливаете HasRequired на автомобиле WithOptional, но вам нужно сообщить EF о ключе, который нужно использовать.В БД PersonID на столе Car должен быть ненулевым.

public class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
    public virtual Car Car { get; set; }
}

public class Car
{
    public int CarId { get; set; }
    public string Make { get; set; }
    public virtual Person Person { get; set; }
}
public class PersonMap : EntityTypeConfiguration<Person>
{
    public PersonMap()
    {
        HasKey(x => x.PersonId);
    }
}

public class CarMap : EntityTypeConfiguration<Car>
{
    public CarMap()
    {
        HasKey(x => x.CarId);
        Property(x => x.Make).IsRequired();
        HasRequired(x => x.Person)
            .WithOptional(x => x.Car)
            .Map(x => x.MapKey("PersonId")); // Tell EF to use the PersonId on the Car to resolve the Person reference.
    }
}

Тогда, когда вы идете, чтобы создать человека и автомобиль ...

var person = new Person { /* set properties */ };
dbContext.Persons.Add(person);
// Or retrieve your Person from the DbSet..

var car = new Car
{
   /* set properties... */
   Person = person // associate the person to the car.
};
dbContext.Cars.Add(car);
dbContext.SaveChanges();

Теперь, если выполучить автомобиль, вы можете получить доступ к их .Person.Если вы нашли человека, у которого есть машина, вы можете получить доступ к его .Car.

...