选项1:1映射,主实体中没有FK

时间:2013-05-15 16:05:53

标签: c# asp.net-mvc entity-framework entity-framework-4

我首先使用实体​​框架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实体可以很好地保存到数据库并正确设置标识。

2 个答案:

答案 0 :(得分:1)

UserId移除House属性,从this.HasRequired...构造函数中删除HouseConfiguration映射,然后在UserConfiguration中使用:

this.HasOptional(x => x.House).WithRequired();

这将定义共享主键关联(即House.IdHouse的主键,同时是[{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; }
}