实体框架错误:ReferentialConstraint中的依赖属性映射到存储生成的列。列:'Id'

时间:2017-05-22 13:37:20

标签: c# sql-server entity-framework

假设我有三个主键表为“存储生成模式”。

Table1Table2以一对一的关系与Table3相关联。这意味着:Table3只能有一个table1

的实例
public partial class table1
{      
    public int Id { get; set; }
    public string name { get; set; }

    public virtual Table3 Table3 { get; set; }
}

public partial class table2
{      
    public int Id { get; set; }
    public string name { get; set; }

    public virtual Table3 Table3 { get; set; }
}

public partial class Table3
{
    public Table3() { }
    public Table3(table1 s) { this.table1 = s; this.table2 = null; }
    public Table3(table2 t) { this.table2 = t; this.table1 = null; }

    public int Id { get; set; }
    public string name { get; set; }

    public virtual table1 table1 { get; set; }
    public virtual table2 table2 { get; set; }
}

控制器

Table1 T1 = new Table1()
            {
                name = obj.table1.name,
            };

db.Students.Add(T1);
db.SaveChanges();   // works sucessfully 
                                // Data in inserted
Table3 t3 = new Table3()
            {
                name = obj.name,
                table1 = T1,
                table2 = null
            };

db.Users.Add(u);  // here error occurs 
db.SaveChanges(); //InvalidOperationException:  

问题:

在控制器中,当我尝试插入数据库时​​,插入了Table1并且Table2引发了错误:

  

ReferentialConstraint中的依赖属性映射到存储生成的列。列:'Id'。

为什么会导致此错误?

通常在数据库中,插入外键的Id。但是,在Entity Framework中,您拥有整个表table3.table1.name的对象。有任何解释可以删除此错误吗?

1 个答案:

答案 0 :(得分:1)

EF中整数键的默认约定是在数据库中生成它们,但是在您有1-1关系的情况下,只有主表可以具有数据库生成的键。然后将该密钥重新用作从属实体的密钥。

例如

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp8
{

    public partial class Table1
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public virtual Table3 Table3 { get; set; }
    }

    public partial class Table2
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public virtual Table3 Table3 { get; set; }
    }

    public partial class Table3
    {
        public Table3() { }
        public Table3(Table1 s) { this.Table1 = s; this.Table2 = null; }
        public Table3(Table2 t) { this.Table2 = t; this.Table1 = null; }

        public int Id { get; set; }
        public string Name { get; set; }

        public virtual Table1 Table1 { get; set; }
        public virtual Table2 Table2 { get; set; }
    }

    class Db : DbContext
    {
        public DbSet<Table1> Table1 { get; set; }
        public DbSet<Table2> Table2 { get; set; }
        public DbSet<Table3> Table3 { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Table1>()
                        .HasOptional(t => t.Table3)
                        .WithOptionalPrincipal(t1 => t1.Table1);

            modelBuilder.Entity<Table2>()
                        .HasOptional(t => t.Table3)
                        .WithOptionalDependent(t => t.Table2);

            modelBuilder.Entity<Table1>()
                        .Property(t => t.Id)
                        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

            modelBuilder.Entity<Table2>()
            .Property(t => t.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

            modelBuilder.Entity<Table3>()
            .Property(t => t.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);


        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new Db())
            {


                Table1 T1 = new Table1()
                {
                    Name = "Foo"
                };

                db.Table1.Add(T1);
                db.SaveChanges();   // works sucessfully 
                                    // Data in inserted
                Table3 t3 = new Table3()
                {
                    Name = "Bar",
                    Table1 = T1,
                    Table2 = null
                };

                db.Table3.Add(t3);
                db.SaveChanges(); 

                var t2 = new Table2()
                {
                    Name = "Baz",
                    Table3 = t3
                };
                db.Table2.Add(t2);
                db.SaveChanges();
            }
        }
    }
}