1

設計數據庫時,兩個表之間存在關係,即JobDocument。一個Job可以有多個Documents,但這些Documents中的一個(並且只有一個)需要標記爲IsCurrent。這並不總是與Job相關的最新Document如何使用「是當前」要求實現一對多關係

在結構上,我可以看到兩種方法。

第一種方法是將DocumentId列添加到Job,將JobId列添加到Document。這將起作用,但會創建一個循環引用:當導入到實體框架中時,最終會出現Job同時具有DocumentDocuments集合的特殊情況。同樣,Document同時具有JobJobs集合。

第二種方法是在Document表中添加一個IsCurrent位標誌。這將起作用,但是在邏輯上使作業具有多個IsCurrentDocuments,這是不允許的。

問題:

1)我是正確的思維有沒有「第三條道路」擺脫這種困境的?

2)假設沒有,哪個更好,爲什麼?我贊成第二個解決方案,因爲它看起來更清潔,我們可以通過業務邏輯強制執行單個IsCurrent。我的同事主張以前的解決方案,因爲它會導致更簡單的C#代碼和對象引用 - 如果我們重命名外鍵,它應該避免由Job/Jobs創建的混淆。

回答

3

如果你的後端是SQL Server,您可以創建一個filtered index以確保每個job最多有一個當前文檔:

CREATE UNIQUE INDEX IX_Documents_Current 
    ON Documents (JobId) where IsCurrent=1 

這樣一來,它不是只是在業務級別執行但是也在數據庫內執行。

+0

太好了,謝謝。我認爲過濾的索引是性能工具 - 我不知道它們可以用來強制執行完整性。 –

+0

@MattThrower - 如果你仔細想想,*任何*唯一索引至少在某些方面強制執行完整性。 –

+0

這麼簡單,如此優雅......明亮等等:總是閱讀**所有**工具的使用文檔。 – tschmit007

1

只是爲了第三種方式(以及爲了好玩):考慮使用不是一點,但是int在作業的文檔中等於max + 1。

然後在{job FK,int表}上創建一個唯一索引。

,您可以:

  • 變化通過更新INT當前,
  • 獲取當前通過搜索最大和
  • 防止由於具有唯一索引的一個以上的電流。
  • 通過對所述int使用min-1來創建新的非當前文檔。

這不是最簡單的實現。

0

是的,還有第三種解決這個難題的方法。您需要一個支持SQL CREATE ASSERTION的DBMS(並且當然支持它正確)。使用這樣的DBMS,您可以聲明適用於您的情況的任何數據規則,並且您的DBMS將爲您執行該規則。

不幸的是,在SQL世界中不存在這樣的DBMS *。在SQL世界之外,有這樣的引擎。 ASSERTIONs是我的木馬,我自己寫了一個。如果你有興趣,谷歌搜索應該很快引導你。

相關問題