【问题标题】:"unable to determine the principal end of an association" for two one to many relationships两个一对多关系的“无法确定关联的主体端”
【发布时间】:2016-01-09 02:53:45
【问题描述】:

我有以下实体:DevicePrinter

public class Device
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int DeviceId { get; set; }

    public int? DefaultPrinterId { get; set; }
    [ForeignKey("DefaultPrinterId")]
    public virtual Printer DefaultPrinter { get; set; }
}

public class Printer
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int PrinterId { get; set; }

    public int? DeviceId { get; set; }
    [ForeignKey("DeviceId")]
    public virtual Device Device { get; set; }
}

设备和打印机之间有两种关系

  • 每台打印机可能托管或不托管在特定设备上,这由 Printer 实体上的 Device 外键表示。这是一对多的关系。
  • 默认情况下,每个设备都将配置为使用特定的打印机。这由DefaultPrinter 外键表示。这是一对多的关系。

当我使用 Entity Framework 生成数据库时,我收到错误消息:“无法确定关联的主体端” 要找到有关此错误如何与一对一关系相关的信息并不难,但是我还没有找到任何关于这与两个一对多关系的关系。

有什么方法可以告诉 EF 我不想定义一对一的关系?

【问题讨论】:

  • 我认为如果没有桥接表,您无法在 EF 中完成这项工作,因为设备和打印机需要共享密钥 (stackoverflow.com/questions/6531671/…)。我认为您将需要设备中的打印机集合和打印机中的设备集合。

标签: c# entity-framework ef-code-first


【解决方案1】:

问题在于您没有指定关系的“结束”。因为这两种关系都不是 1-1,而是 1-n。

Device 可以有一个DefaultPrinter,这意味着Printer 可以是许多设备的“默认打印机”。

使用 Fluent API 可以轻松解决(移除现有的 [ForeignKey] 属性)。像这样:

modelBuilder.Entity<Printer>()
    .HasOptional(i => i.Device)
    .WithMany() //we don't have navigation property on the other side
    .HasForeignKey(i => i.DeviceId);

modelBuilder.Entity<Device>()
    .HasOptional(i => i.DefaultPrinter)
    .WithMany() //we don't have navigation property on the other side
    .HasForeignKey(i => i.DefaultPrinterId);

假设您想知道哪些设备将特定打印机作为其“默认打印机”。

public class Device
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int DeviceId { get; set; }

    public int? DefaultPrinterId { get; set; }

    public virtual Printer DefaultPrinter { get; set; }

    //that's new
    public virtual ICollection<Printer> PrintersThatLoveMe { get; set; }
}

public class Printer
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int PrinterId { get; set; }

    public int? DeviceId { get; set; }

    public virtual Device Device { get; set; }

    //that's new
    public virtual ICollection<Device> DevicesThatLoveMe { get; set; }

}

映射:

modelBuilder.Entity<Printer>()
    .HasOptional(i => i.Device)
    .WithMany(i => i.PrintesThatLoveMe)
    .HasForeignKey(i => i.DeviceId);

modelBuilder.Entity<Device>()
    .HasOptional(i => i.DefaultPrinter)
    .WithMany(i => i.DevicesThatLoveMe)
    .HasForeignKey(i => i.DefaultPrinterId);

希望对你有帮助!

【讨论】:

    猜你喜欢
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    相关资源
    最近更新 更多