Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use try-catch block to connect to the Entity Framework?

I am a new ASP.NET developer and this is my first time to use Linq-to-Entities and Entity Framework. My problem now is about using the best practice of connecting to the Entities or Database. I know that try-catch block is very expensive. But should I use them whenever I need to connect to the database? I am asking this question because I have around 20 entities and in my Data Access Layer, I have all the GetData() methods for each one of these entities. Could you please advise on this?

C# code:

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;
}
like image 851
Technology Lover Avatar asked Jan 03 '14 16:01

Technology Lover


2 Answers

You definitely don't want to catch Exception here because you could mask other (possibly bigger) problems with your code.

Generally, you should only catch exceptions if you intend on handling them in some way. For example, in your scenario you might want to display a UI message if the connection fails. The best approach for this is to let the exception bubble up to the layer in which you actually want to handle it in.

To avoid coupling between your layers a good approach is to catch the storage-specific exception in the DAL and raise a more application-specific exception which you can then handle in the upper layers e.g.

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;
}

UI

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

If you need guidance on how to go about implementing a custom exception, see this answer.

like image 191
James Avatar answered Nov 10 '22 11:11

James


try-catch block is very expensive.

Try is cheap, catch is cheap, throw is expensive. So, if code execution follows normal path (does not produce exceptions), try-catch's are no problem. (BTW, expensive throw is one reason why you should avoid exception-based logical flows in your code) Even if you avoid try-catch block, throwing is still expensive.

should I use them whenever I need to connect to the database?

This comes down to your judgement call. Generally, it is a bad idea to have naked throws between layers of your app. It is equally bad idea to have multiple catches within a single block of your app.

I'd say you definitely want to catch Exception on top level of your DAL: client should not care about your internal problems (DB connections, timeouts, bad logins, etc.).

And here I have to basically just quote previous answer:

to avoid coupling between your layers... raise a custom, application specific, exception which you can then handle in the upper layers

Two good ideas for your catch's is to (1) log exception (so DAL's side knows about it afterwards), (2) have unit tests in place (pre-execute SQL to write known data into DB, then invoke GetData()) so that you can detect general problems prior releasing DAL for client's use

like image 34
user270576 Avatar answered Nov 10 '22 11:11

user270576