2010-08-22 31 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