使用Entity Framework插入一对一或零时缺少Id

时间:2018-05-23 17:16:18

标签: entity-framework entity-framework-6

对SQL Server使用EF6,在保存具有一对一或零关系的记录时,如何按顺序配置映射 对于" 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 :(得分:1)

你不想要双映射,你的密钥有点笨拙。汽车需要一个人,所以PersonID不会是可空的,因为一个人可能或可能没有汽车。如果你想在车上使用PersonId,那么在人和车之间它是1-0..1。从这里你可以在Car WithOptional上设置HasRequired但你需要告诉EF关于要使用的密钥。在DB中,Car表上的PersonID需要不可为空。

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。