代码之家  ›  专栏  ›  技术社区  ›  Nestor

在重新插入实体框架后,尝试重新插入实体导航

  •  0
  • Nestor  · 技术社区  · 7 年前

    我有以下型号:

    [Table("Facts")]
    public partial class Facts
    {
      [Key]
      public Guid ID { get; set; }
      public Guid UserID { get; set; }
      [ForeignKey(nameof(UserID))]
      public Users Users { get; set; }
      //other properties are ommitted
    }
    

    migrationBuilder.CreateTable(
                name: "Facts",
                columns: table => new
                {
                    ID = table.Column<Guid>(nullable: false),
                    UserID = table.Column<Guid>(nullable: false),
                //other properties are ommitted
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Facts", x => x.ID);
                    table.ForeignKey(
                        name: "FK_Facts_Users_UserID",
                        column: x => x.UserID,
                        principalTable: "Users",
                        principalColumn: "ID",
                        onDelete: ReferentialAction.Cascade);
                });
    

    因为它有一个导航属性,所以我将其设置为现有的ID(这是必需的)。

    这是保存方法:

     public async Task SaveData<T>(List<T> data, bool isNew) where T : class
     {
       if (data == null)
          throw new ArgumentNullException(nameof(data));
       try
       {
         if (isNew)
           context.Set<T>().AddRange(data);
         else
         {
           context.Set<T>().AttachRange(data);
           data.ForEach(d => (context as DbContext).Entry(d).State = EntityState.Modified);
         }
         await context.SaveChangesAsync();
       }
       catch (Exception ex)
       {       
         throw;
       }
     }
    

    当我进入save方法时,我有以下状态(ID已设置,导航属性对象为null):

    enter image description here

    AddRange ,我有以下状态(ID已设置,导航属性对象为 非空 ):

    enter image description here

    Microsoft.EntityFrameworkCore.DbUpdateException:发生错误 在更新条目时。有关详细信息,请参见内部异常。---> 约束失败'

    如何防止重新插入已存在的导航属性?

    Failed executing DbCommand (105ms) [Parameters=[@p0='84ddca86-3f8a-41f1-aaed-2c65bd1cb384' (DbType = String),...@p18='e33f7939-bc35-4d82-b68b-e1cc0cf32ff1' (DbType = String)...]
    INSERT INTO "Facts" ("ID", ... "UserID",...)
          VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19, @p20, @p21, @p22, @p23, @p24, @p25, @p26, @p27, @p28, @p29);
    Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 19: 'FOREIGN KEY constraint failed'.
    

    更新2

    我做了一些仿真器测试,发现了以下几点。

    数据 Users 表最初通过SQL脚本插入,代码如下:

    public async virtual Task ExecuteCommandAsync(string sqlCommand)
    {
      await context.Database.ExecuteSqlCommandAsync(new RawSqlString(sqlCommand));
    }
    

    如您所见,记录存在:

    enter image description here

    当我用 SaveData ,其ID存储为 二进制数据 :

    enter image description here

    所以,当试图将二进制数据转换为文本时,实体框架核心可能有点混乱?还是不知道为什么取回能正常工作。

    0 回复  |  直到 7 年前