EF Core 错误地为 Array 执行多次插入

Posted

技术标签:

【中文标题】EF Core 错误地为 Array 执行多次插入【英文标题】:EF Core incorrectly doing multiple inserts for Array 【发布时间】:2021-06-28 00:51:50 【问题描述】:

我还是 Entity Framework 的新手,在我正在开发的 .NET Core API 服务上将记录插入数据库时​​遇到了一个问题。

总结一下,我不是从 EF 生成架构,而是在 SQL 中创建表并让 EF 访问它。

我有一个类似这样的模型对象:

[Table("events")]
public class Event

    [Key]
    [Required]
    [Column("id")]
    public Guid Id  get; set; 

    public string EventName  get; set; 

    public List<Session> Sessions  get; set; 


[Table("sessions")]
public class Session

    [Key]
    [ForeignKey("FK_events-sessions")]
    [Column("eventId")]
    public Guid EventId  get; set; 

    public byte Hour  get; set; 

    public byte Day  get; set; 

    public byte Month  get; set; 

除此之外,在上下文类中,我声明了一对多关系: modelBuilder.Entity&lt;Event&gt;().HasMany(s =&gt; s.Sessions);

在 SQL DB 中,表列具有匹配的名称,但都以小写字母开头。

我遇到的问题是,当我执行 POST 操作时,添加并保存了具有多个会话的 Event 对象时,会引发错误:

Microsoft.EntityFrameworkCore.DbUpdateException:保存实体更改时出错。有关详细信息,请参阅内部异常。 ---> Microsoft.Data.SqlClient.SqlException (0x80131904):在 SET 子句或 INSERT 的列列表中多次指定列名“eventId”。在同一个子句中,一列不能分配多个值。修改子句以确保一列只更新一次。如果此语句更新或将列插入到视图中,列别名可以隐藏代码中的重复。

我在 EF 上启用了信息日志记录,我看到它这样做了:

INSERT INTO [sessions] ([eventId], [Hour], [Day], [EventId], [Month])
VALUES (@p0, @p1, @p2, @p3, @p4);
      INSERT INTO [sessions] ([eventId], [Hour], [Day], [EventId], [Month])
      VALUES (@p0, @p1, @p2, @p3, @p4);

如您所见,由于某种原因,它两次添加了 Id 列。 我想知道第一个是我用[Column("eventId")] 注释的映射,另一个是从对象Event 生成的映射。

有什么想法吗?

谢谢。

【问题讨论】:

您是否尝试删除 [Column("eventId")] 语句? 为了省事,请使用scaffold-dbcontext 命令自动为您生成dbcontext 和模型。那么一切都会正常进行。并确保您的表在 db 中有关系。 @heuristican 没有它,它将执行 INSERT INTO [sessions] ([EventId], [Hour], [Day], [EventId1], [Month]) @Asherguru 我做了一些研究并试图比较会生成的内容和我拥有的内容,但我似乎遇到了一个错误:github.com/dotnet/efcore/issues/24251 使用稳定的 NET 5。我在 NET 5 中使用了脚手架-dbcontext。没问题。预览版/测试版总是有很多错误。 【参考方案1】:

我已经解决了这个问题。

我的数据库架构有 Sessions,其键仅为外键,这使得条目不是 100% 唯一的。 它允许有重复的条目。

目前,我决定将Sessions 的主键更改为使用EventIdDay 的复合键。

我当前的OnModelCreating modelBuilder 如下:

modelBuilder.Entity<Session>()
  .HasOne(c => c.Event)
  .WithMany(s => s.Sessions)
  .HasForeignKey(k => k.EventId);

modelBuilder.Entity<Session>()
  .HasKey(k => new  k.EventId, k.Day);

希望它在未来对其他人有所帮助。

【讨论】:

以上是关于EF Core 错误地为 Array 执行多次插入的主要内容,如果未能解决你的问题,请参考以下文章

.net ef core 检查是不是插入成功

.net ef core 检查是不是插入成功

使用EF Core 6执行原始SQL查询

ef core 子对象集合插入顺序

如何使用EF Core Code-First桥接自己的表

如何使用 EF Core 5 执行存储过程 ORACLE?