我首先使用实体框架4,mvc4和代码。
我正在努力创建一个选项1:1映射,其中具有可选1:1映射的主实体中没有FK:
public class User
{
[Column("user_id")]
public int Id {get;set;}
public virtual House House {get;set;} // optional mapping
}
public class House
{
[Column("house_id")]
public int Id {get;set;}
[Column("user_id")]
public int UserId {get;set;}
}
注意用户表没有teh houseId列。
如何正确映射?
注意:下面的方法不是我真正想要做的,因为它迫使我在House模型上添加一个导航属性也回到User。
我试过这个方法,虽然我不得不在House模型中添加一个我不想做的虚拟属性:How do I code an optional one-to-one relationship in EF 4.1 code first with lazy loading and the same primary key on both tables?
所以我的配置与上面的尝试相似:
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
this.ToTable("User", SchemaName);
this.HasKey(x => x.Id);
this.HasOptional(x => x.House);
}
}
public class HouseConfiguration : EntityTypeConfiguration<House>
{
public HouseConfiguration()
{
this.ToTable("House", SchemaName);
this.HasKey(x => x.Id);
this.HasRequired(vc => vc.User).WithRequiredDependent(v => v.House);
}
}
但是当我这样做时,保存模型我得到了这个错误:
Cannot insert explicit value for identity column in table 'House' when IDENTITY_INSERT is set to OFF
注意:如果没有上述设置(映射和配置),House实体可以很好地保存到数据库并正确设置标识。
答案 0 :(得分:1)
从UserId
移除House
属性,从this.HasRequired...
构造函数中删除HouseConfiguration
映射,然后在UserConfiguration
中使用:
this.HasOptional(x => x.House).WithRequired();
这将定义共享主键关联(即House.Id
是House
的主键,同时是[{1}}的外键)。
如果在User
表中有一个单独的外键列user_id
的现有数据库,并且此列具有唯一的键约束以在数据库中强制实施一对一关系,则不能将此映射为与Entity Framework的一对一关系,因为EF不支持外键一对一关联。
在这种情况下,您必须将此映射为一对多关系,遗憾的是,您无法在委托人House
上拥有一个引用House
。您将不得不使用User
es的集合(并确保在业务逻辑中您永远不会向此集合添加多个元素,否则在保存时,由于违反了唯一的FK约束,您将获得异常在House
表中)或House
中根本没有导航属性。但是,您需要实体User
中的导航参考User
,以便EF能够映射关系(至少需要关系一侧的导航属性)。
答案 1 :(得分:0)
无法回滚到EF4,但之前只是以类似的方式使用它,所以不要相信这已经改变了。
您需要在House对象上设置Key并将其设置为DB generated:
using System.ComponentModel.DataAnnotations.Schema
using System.ComponentModel.DataAnnotations
...
public class House
{
[Column("house_id")]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Column("user_id")]
public int UserId { get; set; }
}