【问题标题】:How to use try-catch block to connect to the Entity Framework?如何使用 try-catch 块连接到实体框架?
【发布时间】:2014-01-03 16:34:38
【问题描述】:

我是一名新的 ASP.NET 开发人员,这是我第一次使用 Linq-to-Entities 和 Entity Framework。我现在的问题是关于使用连接到实体或数据库的最佳实践。我知道 try-catch 块非常昂贵。但是每当我需要连接到数据库时,我应该使用它们吗?我问这个问题是因为我有大约 20 个实体,并且在我的数据访问层中,我拥有每个实体的所有 GetData() 方法。能否请您就此提出建议?

C#代码:

public static IEnumerable<Items> getData()
{
    List<Items> itemsList = new List<Items>();
    try
    {
        using (ItemsDBEntities context = new ItemsDBEntities())
        {
            itemsList = (from item in context.Items
                         select new Items()
                         {
                             ID = item.ID,
                             Code = item.Code,
                             Name = item.Name,
                             StatusID = item.StatusID
                         }).ToList();
        }
    }
    catch (EntityException ex)
    {
        //something wrong about entity
    }
    catch (Exception ex)
    {
        //Don't know what happend... 
    }
    return itemsList;
}

【问题讨论】:

  • "我知道 try-catch 块非常昂贵" - 我不会说 非常 昂贵,但是,有一些开销。

标签: c# asp.net entity-framework-4


【解决方案1】:

你绝对想在这里捕捉Exception,因为你可以用你的代码掩盖其他(可能更大的)问题。

一般来说,如果您打算以某种方式处理异常,您应该只捕获异常。例如,在您的场景中,您可能希望在连接失败时显示 UI 消息。最好的方法是让异常冒泡到你真正想要处理它的层。

为了避免层之间的耦合,一个好的方法是在 DAL 中捕获特定于存储的异常并引发更多特定于应用程序的异常,然后您可以在上层处理该异常,例如

DAL

public static IEnumerable<Items> getData()
{
    List<Items> itemsList = new List<Items>();
    try
    {
        using (ItemsDBEntities context = new ItemsDBEntities())
        {
            itemsList = (from item in context.Items
                         select new Items()
                         {
                             ID = item.ID,
                             Code = item.Code,
                             Name = item.Name,
                             StatusID = item.StatusID
                         }).ToList();
        }
    }
    catch (EntityException ex)
    {
        throw new ConnectionFailedException(ex);
    }
    return itemsList;
}

用户界面

try
{
    var items = Repo.getData();
    ...
}
catch (ConnectionFailedException)
{
    MessageBox.Show("There was a problem accessing the database, please try again.");
}

如果您需要有关如何实施自定义异常的指导,请参阅answer

【讨论】:

  • 感谢您的帮助,非常感谢您的清晰解释。还有一个问题,如果我有一个自定义错误日志记录类,我应该在你的答案中使用它吗?我应该将它包含在 DAL 还是 UI 中?
  • @TechnologyLover 这完全取决于您,但是,日志框架通常根植于您的应用程序中,因此它可以应用到任何地方。
【解决方案2】:

try-catch 块非常昂贵。

尝试很便宜,抓很便宜,扔很贵。 因此,如果代码执行遵循正常路径(不产生异常),try-catch 就没有问题。 (顺便说一句,昂贵的 throw 是您应该在代码中避免基于异常的逻辑流的原因之一) 即使你避免了 try-catch 块,投掷仍然很昂贵。

我是否应该在需要连接到数据库时使用它们?

这取决于您的判断。 通常,在应用程序的各层之间进行裸投是一个坏主意。在应用程序的一个块中包含多个捕获同样是个坏主意。

我想说你肯定想要在 DAL 的顶层捕获异常:客户端不应该关心你的内部问题(数据库连接、超时、错误登录等)。

在这里我基本上只引用之前的答案:

为了避免层之间的耦合... 引发一个自定义的、特定于应用程序的异常,然后您可以 在上层处理

catch 的两个好主意是 (1) 记录异常(以便 DAL 方面事后知道),(2) 进行单元测试(预先执行 SQL 以将已知数据写入数据库,然后调用 GetData()) 以便在发布 DAL 供客户使用之前检测一般问题

【讨论】:

  • 在你的应用程序的一个块中包含多个捕获同样是个坏主意” - 你认为多个捕获是个坏主意的理由是什么?
  • 澄清一下,“多个”是指多个,其中一个包含在另一个中。原因很简单——拥有从内部 catch 到外部 catch 的代码路径意味着投掷,而投掷代价高昂。如果没有导致外部捕获的代码路径,那么它就是多余的。
【解决方案3】:

除非你打算用它做点什么,否则不要捕获异常。例如,您可能想在允许异常冒泡之前重试连接到 db x 次。我建议不要费心将代码包装在 try catch 中,除非你打算做一些特别的事情。

【讨论】:

  • 我将在 catch 块中添加一条错误消息。这是一个好方法吗?我想如果我不使用 try-catch,那么用户会看到一条错误消息,这不是处理它的好方法。你怎么看?
  • @TechnologyLover 你真的不想在你的 DAL 中放入错误消息。
  • @James,你有什么建议?我应该使用 try-catch 块吗?还是使用块就足够了?
  • @TechnologyLover 查看答案。
猜你喜欢
  • 2015-02-22
  • 1970-01-01
  • 2016-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-10
  • 2013-08-05
  • 1970-01-01
相关资源
最近更新 更多