我首先使用EF 6.1代码构建应用程序。实体模型包含以下类:
public enum UnitSystem {
English,
Metric
}
public enum UnitTypes {
Volume,
Weight,
Other
}
public class Unit {
[DatabaseGenerated( DatabaseGeneratedOption.Identity ), Key]
public int UnitId { get; set; }
[Required, MaxLength( 128 ), Index( IsUnique = true )]
public string UnitName { get; set; }
[Required]
public UnitSystem UnitSystem { get; set; }
[Required]
public UnitTypes UnitType { get; set; }
public virtual ICollection<Item> Items { get; set; }
}
public class Item {
[DatabaseGenerated( DatabaseGeneratedOption.Identity ), Key]
public int ItemId { get; set; }
[Required, MaxLength( 128 ), Index( IsUnique = true )]
public string ItemName { get; set;
[Required]
public int UnitId { get; set; }
[ForeignKey( "UnitId" )]
public virtual Unit Units { get; set; }
/// Other unimportant properties
}
public class UnitConversion {
[Required, Key, Column( Order = 0 )]
public int FromUnitId { get; set; }
[ForeignKey( "FromUnitId" )]
public virtual Unit FromUnit { get; set; }
[Required, Key, Column( Order = 1)]
public int ToUnitId { get; set; }
[ForeignKey( "ToUnitId" )]
public virtual Unit ToUnit { get; set; }
[Key, Column( Order = 2 )]
public int? ItemId { get; set; }
public virtual Item Item { get; set; }
[Required]
public double ConversionFactor { get; set; }
}
当EF构建数据库时,我收到“Introducing FOREIGN KEY CONSTRAINT”消息。我需要ItemId
属性可以为空,如果它不为null,我需要它作为Items
表中的外键。
创建此关系以避免级联删除错误的正确方法是什么?
修改
我不再在ItemId
列上收到错误;现在我收到的是FromUnitId
或ToUnitId
列,或两者都有。
我已将导航属性添加到Unit
类:
[ForeignKey("FromUnitId")]
public virtual ICollection<UnitConversion> FromConversions { get; set; }
[ForeignKey("ToUnitId")]
public virtual ICollection<UnitConversion> ToConversions { get; set; }
这是我收到的错误消息的全文:
在表'UnitConversions'上引入FOREIGN KEY约束'FK_dbo.UnitConversions_dbo.Units_ToUnitId'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。
UnitConversions
表和Units
表之间应该存在零或一对多的关系。当我尝试创建对modelBuiloder.Entity<UnitConversions>().WillCascadeOnDelete(false)
的调用时,IntelliSense不会显示WillCascadeOnDelete
方法,并且代码将无法编译。
答案 0 :(得分:0)
首先,我建议您快速阅读entityframeworktutorial,以确保按照建议设置密钥。对于1比1的关系,这有点棘手;基本上是“孩子”的主键。是“父母”的外键。
或者,您可以在数据上下文中使用流畅的API并执行类似的操作以确保关系和级联按预期方式运行:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Student>().HasOptional(e => e.StudentAddress)
.WithRequired(m => m.Student);
modelBuilder.Entity<StudentAddress>.WillCascadeOnDelete(false);
}
这表示学生有一个可选的StudentAddress,并且StudentAddress有一个必需的学生,当StudentAddress被删除时,学生没有。