【问题标题】:Entity Configuration issue The INSERT statement conflicted with the FOREIGN KEY constraint实体配置问题 INSERT 语句与 FOREIGN KEY 约束冲突
【发布时间】:2021-09-20 07:29:24
【问题描述】:

我有 2 张桌子。 TutorUser一位用户将拥有一位导师(一对一的关系),这就是这种关系。

我得到了这个例外:

保存上下文类型“App.inf.dt.DatabaseContext”的更改时,数据库中发生异常。

Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。

Microsoft.Data.SqlClient.SqlException (0x80131904):INSERT 语句与 FOREIGN KEY 约束“FK_Tutors_Users_UserId”冲突。冲突发生在数据库“PIMP22”、表“dbo.Users”、列“Id”中。

在 Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔型 breakConnection,Action1 wrapCloseInAction) at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction)
在 Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)

我的实体配置如下所示:

builder.HasOne(c => c.Tutor)
            .WithOne(c => c.User)
            .HasForeignKey<Tutor>(cc => cc.UserId)
            .OnDelete(DeleteBehavior.Restrict);

我想知道我的实体配置是否有任何问题?有人可以帮我解决这个问题吗?

注意:我有一个User 记录已经保存在数据库中。 ID 是 1。

更新

List<User> u = new List<User>
{
       Name= "User 1",
};

                
databaseContext.Users.AddRange(u);

List<Tutor> t = new List<Tutor>
{
       DisplayName = "tut1",
       UserId = 1
};

                
databaseContext.Tutors.AddRange(t);

await databaseContext.SaveChangesAsync();

【问题讨论】:

  • 向我们展示导致此异常的代码!
  • 我已经添加了相关的代码块。如果您需要任何其他信息,请告诉我。谢谢。
  • 你能告诉我们UserTutor具有导航属性的类吗?
  • 好吧,您在数据库中没有 UserId = 1 的用户。这个List&lt;User&gt; u有什么用?另外,你最好也展示一下课程。并给出EF核心版本。

标签: c# .net-core entity-framework-core


【解决方案1】:

您说数据库中有一个 id 为 1 的用户。

你正在创建一个新的并在没有 Tutor 的情况下添加到上下文中

List<User> u = new List<User>
{
   Name= "User 1",
};
databaseContext.Users.AddRange(u);

如果上下文需要为新用户创建的导师,它将抛出异常(您可以使用验证错误捕获它)

如果创建一个虚拟道具并添加引用该对象的导师怎么办?忘记 id,它将由 EF 使用 scope_identity() 自动分配

User.Tutor = new Tutor { DisplayName = "tut1"}

【讨论】:

    【解决方案2】:

    你能这样定义你们的关系并再次尝试更新吗?

    User 课程将是:

    //No relationship properties
    builder.HasOne<Tutor>(x => x.Tutor)
        .WithOne(x => x.User)
        .HasForeignKey<Tutor>(x => x.UserID);
    

    Tutor 课程将是:

    public int UserID { get; set; }
    public virtual User User{ get; set; }
    
    builder.HasOne<User>(x=> x.User)
        .WithOne(x=> x.Tutor)
        .HasForeignKey<Tutor>(x=> x.UserID)
        .OnDelete(DeleteBehavior.NoAction);
    

    【讨论】:

    • 这与 OP 已经拥有的映射基本相同。仅添加了 OnDelete 调用。剩下的两个映射做同样的事情,一个映射就足够了。我不明白这是如何解决问题的。
    • @GertArnold 一对一是一个棘手的关系。以我的方式,您只保留一个外键就足够了,可以处理相关数据。这就是为什么我们需要定义没有foreignKey的另一端。如果你不定义另一边,你将无法获得相关数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-27
    相关资源
    最近更新 更多