2010-08-22 71 views
1

存儲在具有數據約束(例如最大字符串屬性長度)的關係數據庫中的數據。客戶端使用數據訪問庫(DAL)來管理ORM的方式(庫+數據域類)DAL。建模數據約束最佳實踐

會在哪裏你親自實施限制的數據? 例如:

數據域類:

class Person 
{ 
private string _name; 
public string Name 
{ 
    get { return _name; } 
    set { _name = StringHelper.Truncate(value, 50) } 
} 
... 
} 

或可能是倉庫:

PersonRepository { 
    public void CreatePerson(Person p) { 
    p.Name = StringHelper.Truncate(p.Name, 50); 
    ... 
    DataContext.Insert(..); 
    } 
} 

或者,你應使用分配給數據領域類屬性的屬性將在資源庫中處理方法通過反射自動化字符串字段截斷。

class Person { 
    [StringConstraint(MaxLength = 50)] 
    public string Name { get; set; } 
} 

PersonRepository::CreatePerson(p) { 
    EntityHelper.ApplyConstraints(p); 
    ... 
} 

或者可能是別的東西?

預先感謝您!

回答

0

在數據庫中是我的偏好。
如果有人試圖插入太長的字符串,則會返回SQL錯誤。這取決於應用程序通過向用戶顯示有用的消息來處理該錯誤。

如果有人有備用訪問權限--SSMS或其他應用程序代碼,它也是集中的。

+0

我有UI來操縱數據,我想拒絕用戶輸入太長的字符串。如果程序會告訴他們'Sql error occurred',那麼數據約束應該以某種方式轉換爲UI,這將是不正常的。 – 2010-08-22 05:06:47

+0

你不會告訴使用SQL錯誤的用戶; SQL錯誤將被應用程序捕獲並且應用程序會呈現該字符串太長的味精。是「通過向用戶顯示有用的消息來處理該錯誤取決於應用程序。」那很難理解?! – 2010-08-22 05:11:37

+0

我明白了,但只要輸入冗長的字符串,而不是花費時間與任何類型的錯誤消息(「嘿!你的名字太長!請刪除10個字符」)的ui-dbms往返,就會更加用戶友好。對於我的意見,應該從dbms級別冒出來。 – 2010-08-22 05:16:46

1

我會做它在商業邏輯層,與業務邏輯類,它是從數據庫中相關的類不同。我不會冒泡sql錯誤或者甚至在數據庫中強制執行它。在我看來,數據庫只應該關注數據的形狀和一致性。不與實際的數據本身。

您的規則大約50個字符是一個業務規則,沒有邏輯,關係或「結構性」的規則。它可能很容易是51個字符或49個。你任意挑選了50個,這很好。這就是業務層對象的用途。執行這些規則。

任何一個企業對數據的訪問,應該再次通過業務層,通過服務,直接引用或選擇其他方法曝光。

唯一「直接」訪問你的數據庫應該再次事情關心的形狀和一致性的數據,而不是實際的數據本身。如備份,複製,集羣,負載均衡,審計等

事情,所以在ORM類只是人的業務對象和人在實際的數據庫的存儲之間的膠水。數據庫應該只關心數據庫的整體形狀和結構以及實際數據存儲的基礎結構和機制。業務對象應該確定對象的「本質」並確定它的真正含義。一個人應該至少有一個名字,他們的年齡不能超過110年,他們的身高不能超過7英尺,等等等等。

這就是我的哲學/經驗法則:-)

+0

好的,謝謝你的理念:) – 2010-08-22 13:44:49

+0

所以現在當長度改變時,你需要更新兩個地方 - 數據庫,*和*業務層... – 2010-08-22 15:19:27

+0

這就是爲什麼我說我甚至不會打擾把數據庫中的驗證。數據庫不應只關注數據本身的邏輯結構,即一個人可能與許多訂單和底層基礎設施有關。更新人員觸發器並進入另一個表格。關於「集中處理以防某人有替代訪問權限」,請參閱我通過BL層對數據庫操作的直接訪問的段落 – Chaitanya 2010-08-23 00:19:17

1

約束是驗證的一部分。業務層負責驗證對象,但在UI中使用相同的驗證邏輯也很方便。共享這種邏輯的方式是使用一些API來標記具有驗證屬性的數據對象。你可以在BL和UI中運行相同的驗證。 DataAnnotations提供了這種功能,它也可以通過驗證應用程序塊來實現。

編輯:這並不意味着你不會在數據庫中放置約束。這隻意味着您應該能夠儘快檢測到約束違規,以節省往返數據庫的時間。

+0

您將在哪裏親自放置DataAnnotation屬性?到「數據域」類或另一層類? – 2010-08-22 13:54:24

+0

這是基於您的應用程序的假設設計的複雜性。如果您使用所有圖層之間共享的簡單對象,此方法效果最佳。如果您爲每個圖層使用不同的對象集合,則必須爲每個集合重複驗證(例如:驗證未暴露給UI的Domain對象以及暴露給UI的DTO對象的另一驗證)。 – 2010-08-22 14:22:16