EF核心複合鍵,一個外部,一個自動遞增

c# entity-framework entity-framework-core sql-server

我有這個實體:

public class PlayerScoreHistory
{
    public int Id { get; set; }

    public int PlayerScoreId { get; set; }

    public DateTime ScoreWhen { get; set; }
}

我需要從這兩個Id字段中創建一個複合鍵。 PlayerScoreId需要一個外鍵PlayerScore.IdId需要是自動遞增ID。

所以,我得到了:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<PlayerScoreHistory>()
        .HasKey(x => new { x.Id, x.PlayerScoreId });
}

這給了我複合鍵。我做了Add-Migration Initial來給我初始遷移。

要獲取外鍵,我只需在constraints參數中添加該行:

 migrationBuilder.CreateTable(
    name: "PlayerScoreHistories",
    columns: table => new
        {
            Id = table.Column<int>(nullable: false),
            PlayerScoreId = table.Column<int>(nullable: false),
            ScoreWhen = table.Column<DateTime>(nullable: false)
        },
    constraints: table =>
        {
            table.PrimaryKey("PK_PlayerScoreHistories", x => new { x.Id, x.PlayerScoreId });
            table.ForeignKey("FK_PlayerScoreId", arg => new {  arg.PlayerScoreId}, "PlayerScores", "Id");
        });

所以有兩個問題:

  1. 如何在OnModelCreating方法中創建外鍵?
  2. 如何將Id列設置為Database Generated字段並確保EF Core不嘗試設置值?

我不確定哪些選項對我開放,因為EF Core非常新......

我得到的兩個錯誤:

1。

當我將此行添加到Id column參數配置時:

Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)

我明白了

當IDENTITY_INSERT設置為OFF時,SQL無法在表'Table'中為identity列插入顯式值[duplicate]

2。

當我刪除該行然後嘗試添加實體時,我得到:

無法在列Id插入null


顯然我在某個地方......


編輯到目前為止

我決定刪除Id列,只使用PlayerScoreIdScoreWhen作為複合鍵....

但是,我仍然有一個問題是如何將OnModelCreating標識PlayerScoreId作為外鍵 - 沒有導航屬性.....

一般承認的答案

但是,我仍然有一個問題是如何將OnModelCreating標識PlayerScoreId作為外鍵 - 沒有導航屬性.....

您可以使用HasOne / WithMany (或HasMany / WithOne )方法來指定導航屬性,並像往常一樣結合HasForeignKey

modelBuilder.Entity<PlayerScoreHistory>()
    .HasOne<PlayerScore>()
    .WithMany()
    .HasForeignKey(e => e.PlayerScoreId);

熱門答案

首先,編輯遷移文件可以根據需要為您提供所需的數據庫,但EF運行時將不會了解這些更改。運行時所需的所有信息都應僅在模型中配置。

因此你得到例外

當IDENTITY_INSERT設置為OFF時,SQL無法在表'Table'中為identity列插入顯式值[duplicate]

因為EF運行時不知道標識列所以它將在insert語句中發送0( default(int) )作為標識列的值。

我無法獲得第二個異常,因為EF不會(也不會)嘗試為int類型屬性插入null,因為在c#world中value不能為null。

現在回答你的問題:

  1. 伊万的回答是正確的。這是在modelbuilder中配置外鍵的方法。

    modelBuilder.Entity<PlayerScoreHistory>()
        .HasOne<PlayerScore>()
        .WithMany()
        .HasForeignKey(e => e.PlayerScoreId);
    

有關如何配置關係的更多信息 - https://ef.readthedocs.io/en/latest/modeling/relationships.html

  1. 要告訴Id是數據庫生成字段,請在模型構建器中使用以下代碼。

    modelBuilder
        .Entity<PlayerScoreHistory>()
        .Property(e => e.Id)
        .ValueGeneratedOnAdd();
    

這將告訴EF在插入實體時生成Id值,如果只為ValueGeneratedOnAdd配置了1個整數列,則為SqlServer轉換為Identity 。有關生成的屬性的更多信息,請訪問https://ef.readthedocs.io/en/latest/modeling/generated-properties.html#value-generated-on-add



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因