首先通过数据注释在EF代码中实现一对一或零关系

时间:2017-01-13 18:10:28

标签: c# entity-framework

db,Cars和Car的图像中有两个实体:

public class Car
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Required]
    public string Title { get; set; }
}

public class CarImage
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Required]
    public int CarID { get; set; }

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

    public string FileName { get; set; }

    public bool IsPrimaryImage { get; set; }
}

一切都很好,工作正常。例如:车载车= 123有5张图片,其中一张已被标记为'主要' (首先上传的图片或由主持人选择)。

然后我决定优化数据库模型:删除IsPrimaryImage并将PrimaryImage添加到Car,如下所示:

public class CarImage
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Required]
    public int CarID { get; set; }

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

    public string FileName { get; set; }
}

public class Car
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Required]
    public string Title { get; set; }

    public int? PrimaryImageID { get; set; }

    public virtual CarImage PrimaryImage { get; set; }
}

(Car 可能不包含图片 - 这就是为什么int?,而不是int

编译,运行 - 失败并显示错误:

  

类型' System.InvalidOperationException'的例外情况发生在   EntityFramework.dll但未在用户代码中处理

     

其他信息:无法确定主要结尾   类型之间的关联' MyApp.Domain.CarImage'和   ' MyApp.Domain.Car&#39 ;.这种关联的主要目的必须是   使用关系流畅的API或数据显式配置   注释

在stackoverlow上发现了许多关于此错误的类似主题:

  • first,commons
  • second,同样的错误,但是1:1的关系,不是我的情况
  • third,看起来像我的情况,因为大约1:0..1但只有流畅的API。

是否可以使用数据注释修复错误 ? EF版本是6。

2 个答案:

答案 0 :(得分:4)

找到正确的方法:

public class Car
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CarID { get; set; }

    [Required]
    public string Title { get; set; }

    public int? PrimaryImageID { get; set; }

    [ForeignKey("CarImageID")]
    public virtual CarImage PrimaryImage { get; set; }
}

public class CarImage
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CarImageID { get; set; }

    [Required]
    public int CarID { get; set; }

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

    public string FileName { get; set; }
}

sql

P.S。 不幸的是,这不适用于此类ID:

public class Car
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
}

public class CarImage
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
}

更新:如果您将属性指定为ID而将ForeignKey指定为Id - 这将导致错误:

  

发生了'System.InvalidOperationException'类型的异常   EntityFramework.dll但未在用户代码中处理

     

其他信息:属性上的ForeignKeyAttribute   “MyApp.Domain.Car”类型的“PrimaryImage”无效。外国的   在依赖类型上找不到密钥名称“Id”   'MyApp.Domain.CarImage'。 Name值应以逗号分隔   外键属性名称列表。

所以,这也有效(区分大小写!):

public class Car
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Required]
    public string Title { get; set; }

    public int? PrimaryImageID { get; set; }

    [ForeignKey("ID")]
    public virtual CarImage PrimaryImage { get; set; }
}

public class CarImage
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Required]
    public int CarID { get; set; }

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

    public string FileName { get; set; }
}

v2

答案 1 :(得分:2)

在这种特殊情况下,您不需要数据注释。你需要帮助EF弄明白 Car '多个图像,而不是Car和Image是指向彼此的随机实体。

public class Car
{
  ...

  public virtual ICollection<CarImage> Images { get; set; } // <-- Adding this relation makes the problem go away :-)

  [ForeignKey("PrimaryImageID")]
  public virtual CarImage PrimaryImage { get; set; }
  public int? PrimaryImageID { get; set; }
}

由A K更新:完整代码是{在Required上没有virtual Car Car的情况下工作,它可以与我的样式指南一起用于ID名称)

public class Car
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Required]
    public string Title { get; set; }

    public int? PrimaryImageID { get; set; }

    [ForeignKey("PrimaryImageID")]
    public virtual CarImage PrimaryImage { get; set; }

    public virtual ICollection<CarImage> Images { get; set; }
}

public class CarImage
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Required]
    public int CarID { get; set; }

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

    public string FileName { get; set; }
}

sql management studio

相关问题