我有一个与另一张桌子有关系的课程。
public class MyClass
{
[Key]
public Guid Id {get; set; }
public virtual OtherClass OtherClass { get; set; }
}
我将它连接到控制器并为CRUD创建视图 - 一切正常。
在DB中创建了一个OtherClass_OtherClassId列,但这不在模型中。
如何在控制器的Create方法中将引用放在此Id列中?
如何在不必每次都创建全新的OtherClass的情况下强制此关系为[必需]?
答案 0 :(得分:3)
带有一些描述的带注释的类:
public class MyClass
{
// [Key] - Don't actually need this attribute
// EF Code First has a number of conventions.
// Columns called "Id" are assumed to be the Key.
public Guid Id {get; set; }
// This reference creates an 'Independent Association'. The Database
// foreign key is created by convention and hidden away in the code.
[Required]
public virtual OtherClass OtherClass { get; set; }
// This setup explicitly declares the foreign key property.
// Again, by convention, EF assumes that "FooId" will be the key for
// a reference to object "Foo"
// This will still be required and a cascade-on-delete property
// like above - an int? would make the association optional.
public int OtherClass2Id { get; set; }
// Leave the navigation property as this - no [Required]
public virtual OtherClass2 { get; set; }
}
哪个更好? Independent associations或声明foriegn键?
独立关联使对象编程更接近。使用OOP,一个对象并不真正关心成员的Id。 ORM尝试覆盖这些关系,取得了不同程度的成功。
声明外键会将数据库问题放入您的模型中,但有些情况下这会使处理EF变得更加容易。
示例 - 当使用所需的独立关联更新对象时,EF将希望将整个对象图放在适当的位置。
public class MyClass
{
public int Id {get; set; }
public string Name { get; set; }
[Required] // Note the required. An optional won't have issues below.
public virtual OtherClass OtherClass { get; set; }
}
var c = db.MyClasses.Find(1);
c.Name = "Bruce Wayne";
// Validation error on c.OtherClass.
// EF expects required associations to be loaded.
db.SaveChanges();
如果您要做的只是更新名称,您还必须从数据库中提取OtherClass,因为它是实体验证或attach a stubbed entity (assuming you know the id)所必需的。如果您明确声明了外键,那么您将不会遇到这种情况。
现在使用外键,您遇到了另一个问题:
public class MyClass
{
public Guid Id {get; set; }
public string Name { get; set; }
public int OtherClassId { get; set }
public virtual OtherClass OtherClass { get; set; }
}
var c = db.MyClasses.Find(1);
// Stepping through dubugger, here, c.OtherClassId = old id
c.OtherClass = somethingElse;
// c.OtherClassId = old id - Object and id not synced!
db.SaveChanges();
// c.OtherClassId = new id, association persists correctly though.
总结 -
独立协会
外键
答案 1 :(得分:0)
EF通常需要手持模型配置。这应该让你开始。但是,首先在EF Code First和DB上做一个好的教程将会非常有益。
以下有:
并通过保持标识OrderTypeId和实际的OrderType ref对象来生成单个OrderType。
公共类订单 { 公共秩序() { OrderItems = new OrderItemCollection(); }
public int OrderID { get; set; }
public DateTime OrderDate { get; set; }
public string OrderName { get; set; }
public int UserId { get; set; }
public virtual User OrderUser { get; set; }
public virtual OrderItemCollection OrderItems { get; set; }
public int? OrderTypeId { get; set; }
public OrderType OrderType { get; set; }
public override int GetHashCode() { return OrderID.GetHashCode();}
} 公共类OrderConfiguration:EntityTypeConfiguration { public OrderConfiguration() { this.ToTable( “命令”); this.HasKey(p => p.OrderID); this.Property(x => x.OrderID).HasColumnName(“ORDER_ID”); this.Property(x => x.OrderName).HasMaxLength(200); this.HasMany(x => x.OrderItems).WithOptional()。HasForeignKey(x => x.OrderID).WillCascadeOnDelete(true);
this.HasRequired(u => u.OrderUser).WithMany().HasForeignKey(u => u.UserId);
this.Property(x => x.OrderTypeId).HasColumnName("ORDER_TYPE_ID");
this.HasOptional(u => u.OrderType).WithMany().HasForeignKey(u => u.OrderTypeId);
}
} 公共类OrderContext:DbContext { protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new OrderConfiguration()); } } “