2012-04-17 30 views
4

在这个特定的应用程序中,没有单独的数据层,数据访问代码位于实体本身中。例如,考虑一个客户实体,然后在Customer.cs文件,其中的成员和属性的定义,则必须方法来加载客户对象,如下当数据库的数据不好时,应该抛出异常吗?

public bool TryLoad(int customerID, out Customer customer) 
{ 
    bool success = false 
    try 
    { 
     //code which calls the db and fills a SqlDataReader 
     ReadDataFromSqlDataReader(reader); 
     success = true; 
    } 
    catch(Exception ex) 
    { 
     LogError(); 
     success = false; 
    } 
    return success; 
} 

现在,在ReadDataFromSqlDataReader(读取器),的TryParse用于将数据从阅读器加载到对象中。例如

public void ReadDataFromSqlDataReader(reader) 
{ 
    int.TryParse(reader["CustomerID"].ToString(), out this.CustomerID); 
    PhoneNumber.TryParse(reader["PhoneNumber"].ToString(), out this.PhoneNumber); 
    ... similar TryParse code for all the other fields.. 
} 

正在使用TryParse来读取读者的所有属性一个很好的做法?一位开发者告诉我,它以TryParse的方式完成比int.Parse更好的性能。但是当你从数据库中读取的值不符合你的代码所期望的值时,你是否想要抛出异常?我的意思是在这种情况下,如果数据库中有错误的电话号码,那么可能对象不应该被初始化,而是用一个空的电话号码加载一个对象?

+0

听起来特殊 – Jodrell 2012-04-17 14:39:42

+0

如果您想要处理不良数据,'TryParse'只有更好的'Parse'性能。 – user7116 2012-04-17 14:41:03

+0

我无法想象表演有什么不同。它吞下异常,因此实际上包含了您将在外部使用.Parse写入的相同代码。 – 2012-04-17 14:41:51

回答

4

是的,遵循快速原型原则,您希望在值返回时无法转换为预期类型时抛出异常。

如果其中一个操作失败,并且您继续如同没有任何事情发生一样,那么您可能会遇到难以捕捉且难以查明的怪异错误:当它们应该更新现有行时将对象添加到数据库,数据神秘消失,狗和猫一起生活......你明白了。另一方面,如果立即抛出异常,您就可以确切地知道问题出在哪里,并且可以在问题变得更糟之前抓住并解决问题。

TryParse如果因为没有必要抛出一个异常(这可能很贵)而失败时,它的工作速度会比Parse快,但是如果你认为事情会成功(这个代码是做不到的使用解析结果),您应该使用Parse获得相同的性能。

+0

因为'TryParse'返回布尔值。所以,我可以''ByPass/Continue'根据'布尔'值'提出'逻辑/任何数据库'请求。我不会让这种情况发生在这样的场景中。为此,我会做日志等 – Pankaj 2012-04-17 15:26:42

0

当数据插入和/或更新时,您正在做什么样的验证?

只要你在这里应用某种形式的验证,我个人不会验证数据库中出来的数据,因为你应该确信你只输入了有效的数据。

+1

你能100%保证它总是会是好数据吗?当dba直接打开表格并输入“stjkerij”作为电话号码时会发生什么? – JonH 2012-04-17 14:43:57

+1

问题在于系统开发时最初没有验证。例如,PhoneNumber不是代码中定义的类型,基本上是一个字符串。几年后,其中一名开发人员将PhoneNumber定义为一种类型,现在大多数情况下只要插入数据,它就是有效的数据。但是,这是旧代码的混乱,我不能100%确定来自数据库的数据总是有效的。另外,如果我失败并记录这些,我实际上可能会清除数据库中的错误数据。 – shashi 2012-04-17 14:52:33

+0

@JonH,无论数据是否好,重要的是你能明智地把它做好,如果不是的话。 – 2012-04-17 14:55:41

0

如果你会处理它,那么是的你应该抛出异常。但是如果你不关心这个异常,并且如果你要过滤正确的数据并使用它(在这个例子中是非零),你可以跳过。

+0

我衷心不同意。调用这种方法的程序员会假设他们获得的对象已经完全填充。给他们一个没有完全填充的对象就是要求麻烦。即使没有处理代码,最好让系统失败壮观,并将您的注意力转移到这样一个事实上,即您有一个错误,而不是让您的其他代码使用这些数据,就像没有任何错误一样。 – StriplingWarrior 2012-04-17 14:49:59

+1

你是对的,但它是一个选项。抛出或不抛出异常取决于你想要做什么。我说如果你在意你应该抛出一个例外,但这可能并非总是如此。也许他想在用户界面的“电话号码”列中显示一条消息,如“您的电话号码无效”。 – 2012-04-17 14:56:32

+0

如果我这样做,它是无效的是一个例外。我会抛出它并将其陷入调用者中,并在调用代码中处理它。 (或mabe陷阱并引发一个自定义的异常,将代码中的消息放入代码中,意味着它不止一件事,意味着你必须做同样的事情或者破坏DRY,并且会导致糟糕的设计,并且使得任何单元测试都依赖于用户界面依赖,所以一个选项是的,一个好的我是可疑的 – 2012-04-17 17:30:19

0

As,TryParse返回布尔值。所以,我可以ByPass/ContinueUpcoming Logic/Any Database请求的基础上Boolean值。我不会让这种情况发生在这样的场景中。对于我会做记录等

解析

  1. 抛出异常。
  2. 使用它,如果你确定值将是有效

的TryParse

  1. 返回一个布尔值,指示是否成功
  2. 它只是试图/内部赶上为什么实施没有例外,所以它是快速的
  3. 在情况下使用它e值可能是无效的
1

将数据插入到数据库时将执行有效验证。这不是一个好的设计,可以在数据库中输入错误的数据。如果数据库包含错误的电话号码,则应要求用户再次输入电话号码,如果电话号码不重要,则可以在电话号码不正确的情况下将电话号码初始化为空。

1

我不会为此使用TryParse。 如果我的分贝有垃圾,我想要解决。 如果数据在解析方面是不明确的(例如Varchar用int或double作为字符串) 我想整理我的模式,TryParse作为类型检测将是一个快速而简单的黑客攻击。

相关问题