Initiate 2 DBContext objects, one for logs, and another for business data inside a C # console application

I am working on a C # console application and I am using the framework 5.0 entity as the data access level with sql server. Now I want to track the changes and save them in the log table. therefore, for this, I initiate 2 DbContext objects, one for business data and another for log data, as shown below:

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(); 

I have now provided separate DbContext objects for my logs for the following reason / s: -

  • if my first entity object cannot save the changes for any reason, such as an unhandled validation error or an attempt to hack the system, etc., then the second entity2 will still be able to save the record in the log. let's take this example. let's say I integrate with the third part API and I expect them to return JSON in a specific format .. now let's say that the return json object was missing data, in this case when I try to add an object that it will pick up and exception ... now, since I have a separate object for logs, the journal entry will be saved (it will not be affected by the business data exception). but if I had one DBContext object, then the log entry would not be saved, since I can not save business data. So my question is to initiate two DBContext objects, one for logs and another for business data - a valid approach to follow, or is it a bad decision to follow?
+5
source share
4 answers

Do not use 2 contexts, you must use a logger (e.g. log4net with AdoNetAppender ). As Evk points out in the comment below, EF will automatically transfer all transactions when you call SaveChanges() , so as soon as an error occurs, nothing will be committed to the database and you can register the error. For instance:

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

Thus, your application will remain clean, you will only be updated when everything is successful, when you call SaveChanges() at the end of the using block and register only when an exception occurs. It is also better to use blocks to always use your context, even if an unexpected exception occurs. The registrar will take care of writing errors to the database in another thread without slowing down your program. Perhaps you can try NLog , I heard that it is better (= easier to configure / use) than log4net, but I still need to give it a try.

+6
source

Having multiple contexts for the same database can be useful if your database contains several database schemas and you want to treat each of them as a separate autonomous area. This is not clear from your code / requirement, if so.

If the tables you work with are in the same database and in the same schema, then I see no reason to use two DbContexts. Even if you have a validation error or an exception, you can still save logs in the same context in your table.

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

EDIT

In my opinion, registration should be independent of your normal transactions, so you do not need to think about this scenario. At the same time, you can save and register in the transaction, but also register if there is an exception. If I'm missing something, I still don't see the need for two DBC texts.

See below for some transactional guidelines.

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

+1
source

There are some problems.

  • We continue to work if we encounter an exception when entering data (this can be if some condition is not affected). But if we get an exception during registration, we don’t handle it?

  • What does our business logic do? If we get the wrong json data, our business logic should check and process it.

    Well, let's say that json is valid, it goes through business logic. We have a string field on db with varchar (20), but the data has 25 characters. So what does our model validation do?

    You have to handle these things at higher levels.

  • He violates a single responsibility. This method should have only one responsibility, which stores the object in db. He should also not be responsible for logging. You must implement it in another class.

    Because of this, your problem arises. You are trying to give two answers to this method. Then you try to select 1 dbcontext or 2 dbcontexts that I need. If you follow a single responsibility, this problem will not arise.

You should implement a registration service. Your classes do not need to know or care about how the logger service handles it. You can save it in db, file or cloud, for example loggly . In addition, your registry service should not use the same context with other classes.

0
source

Entity Framework 5 primary code migrations can only process one DbContext instance per physical database instance. Primary code migrations of Entity Framework 6 can manage multiple DbContext instances for a physical database instance.

Check out a pretty nice example:

http://www.dotnet-tricks.com/Tutorial/entityframework/2VOa140214-Entity-Framework-6-Code-First-Migrations-with-Multiple-Data-Contexts.html

-2
source

Source: https://habr.com/ru/post/1246510/


All Articles