如何通过非主键创建一对一关系(EF First Code)

时间:2014-12-27 09:02:02

标签: c# entity-framework orm ef-code-first one-to-one

我有两个班级'Car'和'CarDetails'

 
    public class Car {

        public int Id { get; set; }

        public Guid CarGuid { get; set; }

        public string Name { get; set; }

        public virtual CarDetails CarDetails { get; set; }
    }

    public class CarDetails {

        public int Id { get; set; }

        public Guid CarGuid { get; set; }

        public string Color { get; set; }

        public int Weight { get; set; }

        [ForeignKey("CarGuid")]
        public virtual Car Car { get; set; }
    }

现在,我想通过'CarGuid'在两个班级之间建立一种关系,但EF不允许我这样做,请帮助我!

1 个答案:

答案 0 :(得分:0)

您无法使用非主键属性/列在两个EF实体/ SQL表之间创建一对一(或一对一或一)关系。您必须使用主键列来实现与EF的这种关系。

public class Car
{
    public int Id { get; set; }

    public Guid CarGuid { get; set; }

    public string Name { get; set; }

    public virtual CarDetails CarDetails { get; set; }
}

public class CarDetails
{
    [Key, ForeignKey("Car")]
    public int Id { get; set; }

    public Guid CarGuid { get; set; }

    public string Color { get; set; }

    public int Weight { get; set; }

    public virtual Car Car { get; set; }
}

根据上述关系,您最终将Car作为主体,CarDetails作为主体。通过将CarDetails.Id作为CarDetails的主键和引用Car.Id的外键,您可以确保每个Car不超过1 CarDetails

但是,从技术上讲,这不是1<->1关系......它是1<->0..1关系。这种类型的模型将允许Car个对象存在而没有任何相应的CarDetils对象。

如果你想要更接近1<->1关系的东西,我相信唯一的方法是使用流畅的模型构建器:

public class CarsDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>();
        modelBuilder.Entity<CarDetails>()
            .HasRequired(x => x.Car).WithRequiredDependent(x => x.CarDetails)
        ;

        base.OnModelCreating(modelBuilder);
    }
}

使用上述定义,除非您在同一SaveChanges操作中保存相应的Car,否则无法保存CarDetails。这与实体框架将接近的1<->1接近。您可以通过类似的方式从关系的另一端实现相同的目标:

public class CarsDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>()
            .HasRequired(x => x.CarDetails).WithRequiredPrincipal(x => x.Car)
        ;
        modelBuilder.Entity<CarDetails>();

        base.OnModelCreating(modelBuilder);
    }
}

参考:http://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx