【问题标题】:How to Create one-to-one relationship by non-primary key (EF First Code)如何通过非主键创建一对一关系(EF First Code)
【发布时间】:2014-12-27 09:02:01
【问题描述】:

我有两个类 '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 不允许我这样做,请帮助我!

【问题讨论】:

  • 为了与 EF 建立一对一的关系,两个表必须共享相同的主键。这意味着CarDetails 应该与Car 具有相同的主键,并且CarDetails 的主键列应该有一个FK。
  • 谢谢。你能写出正确的代码吗? (当然可以在数据库中完成。)

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


【解决方案1】:

您不能使用非主键属性/列在两个 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);
    }
}

根据上述定义,您无法保存Car,除非您在同一个SaveChanges 操作中还保存了相应的CarDetails。这与实体框架将带您的1&lt;-&gt;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

【讨论】:

  • 我想通过 'CarGuid' 在两个类之间建立关系,但 EF 不允许我这样做
  • 您不能使用CarGuid 建立一对一的关系,除非CarGuid 是两个类(表)的主键。 EF 是不可能的。
猜你喜欢
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多