Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initiating 2 DBContext objects one for logs and the other for Business Data inside c# console application

I am working on a c# console application, and I am using entity framework 5.0 as the data access layer with sql server. now I want to track the changes and save them inside a log table. so to do so I am initiating 2 DbContext objects one for the business data while the other for the log data, as follow:

class Sync
    {
        static void Main(string[] args)
        {
            string syncResult = "Sync started";
            Entities entities = new Entities();//for business data
            Entities entities2 = new Entities();//for logs
            try
            {
              //code goes here
              entities.SaveChanges();
            }
            catch (Exception e)
            {
                syncResult = string.IsNullOrEmpty(e.Message) ? "Error" : e.Message;

            }
            entities.Dispose();
            entities2.LogHistories.Add(new LogHistory() { Description = syncResult });
            entities2.SaveChanges();
            entities2.Dispose(); 

now i provided separate DbContext objects for my logs , for the following reason/s:-

  1. if my first entity object is not able to save the changes , due to any reason such as unhandled validation error, or trying to hack the system, etc.. then the second entities2 will still be able to save the log entry. let take this example. let say I am integrating with a 3rd part API and I am expecting them to return JSON in a specific format.. now let assume that the return json object had missing data, in this case when I try adding the object it will raise and exception ... now since I am having separate entity object for the logs then the log entry will be saved (will not be affected by any business data exception). but if I was having a single DBContext object then the log entry will fail to save since I am unable to save the business data .. so my question is if initiating 2 DBContext objects one for logs and the other for business data a valid approach to follow, or it is a bad decision to follow?
like image 421
john Gu Avatar asked Apr 06 '16 01:04

john Gu


2 Answers

Don't use 2 contexts, you should use a logger (for example log4net with AdoNetAppender). As Evk points out in the comment down below, EF automatically wraps everything up into a transaction when you call SaveChanges(), so as soon as an error occurs, nothing will be committed to the database and you can log the error. For example:

static void Main(string[] args)
{
    ILog log = LogManager.GetLogger("Entities");

    using(var ctx = new Entities())
    {
        try
        {
            ...
            ctx.SaveChanges();
        }
        catch(Exception ex)
        {
           log.Error(ex.Message);
        }
    }
}

This way your application stays clean, you will only update when everything succeeds when you call SaveChanges() at the end of the using block, and only log when an exception happens. Also it's better with the using blocks to always dispose of your context, even if an unexpected exception would occur. The logger will take care of writing the errors to the database in another thread without slowing down your program. Perhaps you can try out NLog, I've heard it's better (= easier to configure/use) than log4net but I still have to give it a try myself.

like image 149
Alexander Derck Avatar answered Nov 01 '22 19:11

Alexander Derck


Having multiple contexts for a single database can be useful if your database contains multiple database schemas and you want to handle each of them as a separate self contained area. Its not clear from your code / requirement if this is the case.

If the tables you are working with are in the same database & same schema, then I can't see a reason for you to use two DbContexts. Even if you have a validation error or exception, you can still save to your log table with the same context.

If you are trying to log errors and / or other relevant information, why not use log4net to do your logging?

EDIT

In my opinion, logging should be independent of your normal transactions so you don't have to think about this scenario. That being said, in a transaction you can save and log, but also log if there is an exception. Unless I'm missing something, I still don't see the need for 2 DBContexts.

Take a look at the following for some guidance around transactions.

https://msdn.microsoft.com/en-us/data/dn456843.aspx

like image 26
William Xifaras Avatar answered Nov 01 '22 17:11

William Xifaras