使用Entity Framework手動輸入密鑰

asp.net c# entity-framework entity-framework-core sql

我試圖首先使用Entity Framework代碼來處理一個簡單的數據庫項目,然後遇到一個我根本想不通的問題。

我注意到EF正在為我的表設置ID,每次自動增加1,完全忽略我為該字段手動輸入的值。經過一些搜索,我的理解是,正確的方法是禁用此行為:

modelBuilder.Entity<Event>().Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

但是現在我只是得到了這個錯誤,我不明白為什麼:

未處理的異常:System.Data.Entity.Infrastructure.DbUpdateException:更新條目時發生錯誤。有關詳細信息,請參閱內部異常---

System.Data.UpdateException:更新條目時發生錯誤。有關詳細信息,請參閱內部異常---> System.Data.SqlClient.SqlException:當IDENTITY_INSERT設置為OFF時,無法在表'Events'中為identity列插入顯式值。

如果它有用,這是有問題的POCO類:

public class Event
{
    [Key, Required]
    public int EventID { get; set; }

    public string EventType { get; set; } //TODO: Event Type Table later on
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public virtual ICollection<Match> Matches { get; set; }
    public virtual ICollection<EventParticipation> EventParticipation { get; set; }
}

提前致謝。

一般承認的答案

默認情況下,Entity Framework假定整數主鍵是數據庫生成的(相當於在Fluent API中添加屬性HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)或調用Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

如果查看創建表的遷移,您應該看到:

   CreateTable(
                "dbo.Events",
                c => new
                    {
                        EventID = c.Int(nullable: false, identity: true),
                        //etc
                    })
                .PrimaryKey(t => t.EventID );

然後,您使用Fluent API將模型更改為DatabaseGenerated.None 。 EF將此放入遷移中:

AlterColumn("dbo.Events", "EventID", c => c.Int(nullable: false, identity: false))

而生成的sql是這樣的:

ALTER TABLE [dbo].[Events] ALTER COLUMN [EventID] [int] NOT NULL

這實際上確實蹲了下來。從列中刪除IDENTITY並非易事。您需要刪除並重新創建表或創建新列,然後您必須複製數據並修復外鍵。因此,EF並沒有為您做到這一點並不奇怪。

你需要弄清楚如何最好地為自己做這件事。您現在可以將遷移回滾到0並從頭開始重新構建您已指定DatabaseGeneratedOption.None ,或者您可以手動更改遷移以刪除並重新創建表。

或者您可以刪除並重新創建列:

DropColumn("Customer", "CustomerId"); 
AddColumn("Customer", "CustomerId", c => c.Long(nullable: false, identity: false));

編輯或您可以使用自定義遷移操作打開/關閉身份


熱門答案

因為我更喜歡屬性,所以為了完整起見,這裡是替代方案:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }

注意:這也適用於EF Core。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow