Dot-Net

Fluent NHibernate Cascade 問題 - 嘗試插入 NULL ID

  • March 8, 2011

我有以下模型和映射(下面的程式碼片段)。

一場比賽從一開始就必須有多個與之相關的比賽答案(多項選擇)。

目前,使用如下所示的 Fluent NHibernate 映射,當我創建一個全新的 Competition 對象,填充屬性,然後創建 3 個全新的 CompetitionAnswer 對象並將它們添加到 CompetitionAnswers 屬性(競爭屬性)時,我希望呼叫 Save在將 1 Competition 行和 3 CompetitionAnswer 行插入數據庫的會話上。

但是,當我嘗試在會話中呼叫 Save 時,它會抱怨 CompetitionId 為 null,並且它無法將 null 插入到該欄位的 CompetitionAnswers 表中 - 這是正確的,但它不應該,但是,我認為NHibernate 會先創建 Competition,然後在 CompetitionAnswers 表中使用新生成的 IDENTITY 值(CompetitionId)?

比賽(模型)

public virtual int CompetitionId { get; private set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
public virtual IList<CompetitionAnswer> CompetitionAnswers { get; set; }

競賽答案(模型)

public virtual int CompetitionAnswerId { get; set; }
public virtual string Answer { get; set; }
public virtual Competition Competition { get; set; }

CompetitionMap(流利的 NHibernate 映射)

public CompetitionMap()
{
   Id(x => x.CompetitionId)
       .GeneratedBy.Native();
   Map(x => x.Title);
   Map(x => x.Description);
   HasMany(x => x.CompetitionAnswers)
       .Cascade.AllDeleteOrphan()
       .KeyColumn("CompetitionId")
       .Inverse();
   Table("Competitions");
}

CompetitionAnswerMap (Fluent NHibernate Mapping)

public CompetitionAnswerMap()
{
   Id(x => x.CompetitionAnswerId)
       .GeneratedBy.Native();
   Map(x => x.Answer);
   References(x => x.Competition)
       .Column("CompetitionId");
   Table("CompetitionAnswers");
}

這是我用來測試此場景的一些範常式式碼,它會生成錯誤:

Competition c = new Competition();

c.Description = "Description";
c.Title = "Title";

CompetitionAnswer a1 = new CompetitionAnswer { Answer = "Answer 1" };
CompetitionAnswer a2 = new CompetitionAnswer { Answer = "Answer 2" };
CompetitionAnswer a3 = new CompetitionAnswer { Answer = "Answer 3" };

c.CompetitionAnswers.Add(a1);
c.CompetitionAnswers.Add(a2);
c.CompetitionAnswers.Add(a3);

session.Save(c);

我一嚐試保存就得到的確切錯誤是:

無法將值 NULL 插入到列“CompetitionId”、表“CompetitionAnswers”中;列不允許空值。插入失敗。該語句已終止。

誰能解釋一下為什麼這目前不起作用?

我很確定,不是 100%,問題出在您的 CompetitionAnswers on Competition 映射中的 Inverse() 規範。Inverse() 指定子記錄負責定義它們與父記錄的關係。大多數情況下,一對多(父級)的“一”側是對像圖的“頂部”,並“擁有”與其子級的關係。父母有孩子,是否保留或放棄孩子以供收養的決定權在於父母。但是,情況並非總是如此。一所大學可能有學生,但真正有權決定他們去哪裡的是學生。在這裡,學生是圖表的“​​頂部”,而學校只是辨識學生出勤的整體記錄。學生可以隨時轉學;

你的情況是第一個:比賽有比賽答案,孩子在邏輯上沒有責任說“我屬於比賽”;相反,競賽“擁有”它的答案集合。刪除 Inverse() 指令應該使 NH 將 Competition 視為對像圖的“頂部”,因此 NH 將插入 Competition,然後是 CompetitionAnswers,現在可以引用其父 ID。

另一件事與問題無關,但如果您要映射到 MS SQL Server 數據庫,並且 ID 列被定義為數據庫中的標識列,我會GeneratedBy.Identity()為 ID 列指定。Native()應該最終使用 Identity,但它也會檢查 HiLo 或 Sequence 方法是否可用。

引用自:https://stackoverflow.com/questions/5235311