2

我有以下模型:

[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):

在此处输入图像描述

之后AddRange,我有以下状态(设置了ID,导航属性对象不为null):

在此处输入图像描述

在 catch 中,我得到以下异常:

Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。---> Microsoft.Data.Sqlite.SqliteException:SQLite 错误 19:'FOREIGN KEY 约束失败'

看起来它试图将导航属性对象作为新项目添加到数据库中。

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

更新

启用 SQL 日志记录后,我得到以下信息(@p0 是 PK,@p18 是 FK):

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));
}

如您所见,记录存在:

在此处输入图像描述

当我用 保存不相关的数据时SaveData,其 ID 存储为二进制数据

在此处输入图像描述

那么,在尝试将二进制数据转换为文本时,Entity Framework Core 可能会感到困惑吗?仍然不知道为什么检索正常工作。

4

0 回答 0