SaveChangesAsync returns exception instead of 0 [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
About SaveChangesAsync method, Microsoft says
it's a task that represents the asynchronous save operation. The task result contains the number of state entries written to the underlying database.
According to that, some programmers use if condition to check the number of rows affected after SaveChangesAsync is run.
Here is an example: How can I confirm if an async EF6 await db.SaveChangesAsync() worked as expected?
But, what happens if an error occurs when calling SaveChangesAsync? Well, contrary to what I expected, which would be "0 lines affected", an exception is thrown, in most cases, a DbUpdateException
"Exception thrown by DbContext when the saving of changes to the database fails."
So, why are there several recommendations for using if (await context.SaveChangesAsync() > 0) once the result from database will never be zero, but instead, an exception?

So, why are there several recommendations for using if (await context.SaveChangesAsync() > 0) once the result from database will never be zero, but instead, an exception?
First off, there are no such official recommendations. The people who provided them have no idea of the semantics of the SaveChanges operation. Which by current official EF Core documentation is:
Returns
Int32
The number of state entries written to the database.
Exceptions
DbUpdateException
An error is encountered while saving to the database.
DbUpdateConcurrencyException
A concurrency violation is encountered while saving to the database. A concurrency violation occurs when an unexpected number of rows are affected during save. This is usually because the data in the database has been modified since it was loaded into memory.
This is for SaveChanges, but the same is for Async version after awaiting it.
So, as it can be seen from the docs, the operation can return 0 and still be successful. It's because the smart update (load/modify/save) might not generate database operation. But still it is saved - because you don't ask "please force write this to database", but "please make sure this data is saved to the database". It's true that if you perform perform forced update, then 0 is never returned. But that's not essential at all.
The more important is, the success of the operation is determined as usual by the lack of exception. I don't know what is the intended usage of the return value - it might be just because it is something "we can return". Or carry over from EF6 which in turn is carry over from ADO.NET etc. Or just use it for some logging if real database CUD occurred. Who knows. But, for sure one should not use it for checking the success as in these (anti) "recommendations".

Related

Is it a bad idea return a tuple instead of throw an exception? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I have a method, that always has to return an object of type MyType. If it returns null it is because I don't have the needed information to return a value.
So I was thinking that a posibility it is to throw an argument exception if I don't have the needed information.
Another solution, it is to return a tuple, first item null or the object as result. The second item a string, null if I can return the value or a string with the reason why it is null.
I was consideration this second option, because I guess it is more versatile, who calls this method, if get a null, can know the reason of why it is null and don't need to handle the exception, that requieres more code. Also, if it is called in the UI layer, it can tell the user what information it is needed.
An exception it is more expensive if it is thrown, and also, from a point of view, I considerate the exception the way to handle something that I can't control in another way, but in this case I can know in advance if I have the needed information or not from the user, so it is not something unexpected like if I try to load a file and the file doesn't exist, for example, or try to connect to a network resource and the network is down.
Also, argument exception it is a generic exception, if I want to show to a user a understanding message but also I want a more detailed message for the developer, it is more complex code.
So I was wondering if really it is a bad idea to return a tuple or it is better to throw an exception.
I think a touple can be very usefull, because it can return the value of the method, but also can provide aditional information in another items.
This is a variant on the Return codes vs exception discussion.
I would recommend using a specialized type rather than just a plain tuple. This should either have a value, or a string/error code. This should force the caller to handle at least one case, for example by having OnSuccess(Action<T>) and OnFail(Action<string) methods. See Result of T for an example
If this is preferable to exceptions somewhat depend on if failure is expected or not. I think it is appropriate for something like a Parse-method. For reading a file I would prefer exceptions since reading the file can fail at any time for many possible reasons. I.e. a result object fits best with a functional style.

Design pattern for multiple DAC and SAC calls [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Scenario- After request validation, I will need to
Call database and update the record. Based on a certain condition on the execution of this database call and request data, I will be calling Service1.
Upon performing this step, I will call another database and update record from the request.
At last I will call audit service to save the transaction details.
This can be achievable in normal code structure. But I am pretty confident there will be plug and play after step 1 or 2, i.e., a database/service call will be introduced in next release after step 1/step 2 (TBD).
I decided to opt for Chain of Responsibility.
Problems
Where ever the operation breaks/exception is generated, code should stop its execution.
Under single Logging object, I am having difficulty to handle the sequential call.
For step 1’s conditional service call, the dynamic modification of the chain of operations is bit complex, as I have to rely on single data type return from the AbstractionHandler.
Is there any alternative design pattern that I can follow?
You have a scenario in which you have a sequence of operations that may or may not occur based on the result of previous operations.
In my opinion you choosing the right pattern, Chain of Responsibility will be a good choice.
You just need to adapt the classic implementaion that allows passing the request along the chain of potential handlers until one of them handles request.
Basicaly, you can change the implementation of each operation so that when its condition is valid, it executes its own logic and returns the result for the next operation in the chain.
So where ever the operation fail, you should't throw exceptions because exceptions must be used for exceptional conditions (any condition that your normal logical flow does not handle); therefore, within a chain of responsibility it is expect that some operation could return a signal to interrupt the chain (expected result).
Considering that, in my opinion you shouldn't throw an exception in this situation. Instead, you should return a controlled signal to stop the flow of the chain.
Regards,

Heavy I/O with events firing much faster than they can be handled, causing problematic backlog [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
In a nutshell, my project is receiving data faster than it can process and then write it to a database (EF6 to SQL Server 2016), and I'm not sure what the best-practice approach is (ditch EF? Offload to database via Service Broker? Something else?) Write events are not being handled fast enough, so they result in cascading event logjams and fatal memory crashes.
The write events are (I want them to be) low-priority, and I'm using async tasks for them. The write events involve a lot of data and a lot of relationships, and EF is just not handling them efficiently (I'm using AddRange, but EF is just sending everything in many single inserts, which I've read is its regular behavior).
I've tried paring back the relationships, and I've moved more processing over to the database, and I've tried using a batched "Delayed"Queue (an observable queue implementation that triggers an "empty me" event when a threshold is met), so that the inbound write events can be handled very quickly (just dump the request in the queue and move on), but this didn't get me anywhere (not surprising, I suppose, since I've basically added a message queue on top of the built-in message queue?).
Please correct me if I'm wrong, but it seems to me that EF is not the right tool for something as write-heavy and relationship-heavy as what I have (I know there are bulk-write extensions...). So, in an effort to resolve this sensibly, would it make sense to bypass EF and do my own bulk-write queries, or is this an appropriate use for Service Broker? With Service Broker, I could just send a dataset in one sproc, which just adds the dataset to the queue, frees the frontend to move on, and the database can handle and build the relationships whenever. Are these solutions sensible or best practice, or am I barking up the wrong tree (or putting lipstick-on-a-pig maybe)?
Thank you.
Please correct me if I'm wrong, but it seems to me that EF is not the
right tool for something as write-heavy and relationship-heavy as what
I have
You are right.
By default like you said, Entity Framework perform one database round-trip for every record to save which is INSANELY slow.
Disclaimer: I'm the owner of Entity Framework Extensions
(The library is not free)
This library allows you to improve Entity Framework Performance.
I'm not sure if our library can help you but it worth a try if you save multiple entities at once.
By example, the BulkSaveChanges is exactly like SaveChanges but way faster by dramatically reducing the database round-trip required.
Bulk SaveChanges
Bulk Insert
Bulk Delete
Bulk Update
Bulk Merge
Example
// Easy to use
context.BulkSaveChanges();
// Easy to customize
context.BulkSaveChanges(bulk => bulk.BatchSize = 100);
// Perform Bulk Operations
context.BulkDelete(endItems);
context.BulkInsert(endItems);
context.BulkUpdate(endItems);
// Customize Primary Key
context.BulkMerge(endItems, operation => {
operation.ColumnPrimaryKeyExpression =
endItem => endItem.Code;
});

Update a record in ASP .Net MVC [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Today in the interview I faced a question tat I had no clue about. Being a newbie into ASP .Net MVC I had no other way but to ask the experts about it.
"In your MVC Application ,data are being stored into a RDBMS System. In a .cshtml page ,there is a button to update the existing records into DB.
Now suppose two users from different parts of the Globe are at the same time are trying to update a common record. But by the the time the second user hits the submit button, you already submitted the update. In that case the second user , when would be pressing the submit won't be able to submit. Instead the page would reloaded for the second user with the updated info, discarding the changes.And then only he would be able to go on with the update"
How could you achieve that in ASP .Net MVC?
I though thought it might be something from the DB Side coding also , but I have no clue how to achieve the same.
You need to implement a strategy for managing concurrency. How you do this depends largely on the business rules of the application and the type of conflict that arises when two or more people attempt to change the same record.
Most often, you will add a column called RowVersion which will be a timestamp type. Whenever you display records to be updated, you also select the current RowVersion value and usually store it in a hidden field. The update operation will include the RowVersion field, which gets a new value, but before you commit an update operation, you compare the RowVersion value you have with the current one in the database. If they are different, someone else has updated the row during the time that it took you to get the record to be updated and then tried to change it. You determine how to proceed based on the application's business rules.
Asynchronous Tasks do the database operations , so even if another user tries to update , the first process runs in the background asynchronously

Should I throw a KeyNotFoundException for a database lookup? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I've got some code that, given an ID, returns an item from the database. If no item matches the given ID, is it appropriate to throw a KeyNotFoundException, or are such exceptions meant only for Dictionary types?
Depending on the framework you're using to access the database (ODBC, ADO.NET, etc.) there's likely a better alternative that the framework would throw.
The System.Data namespace contains several such exceptions as examples: http://msdn.microsoft.com/library/system.data.
Really, though, as long as you document what exception you're throwing and in what conditions it doesn't matter too much. Using something common is best because people may assume, but if they are reading documentation they will handle whatever exception you say would be thrown.
The MSDN page for KeyNotFoundException states:
The exception that is thrown when the key specified for accessing an element in a collection does not match any key in the collection.
Semantically a KeyNotFoundException would be appropriate. Just make sure your error message is descriptive enough to actually help when debugging. Also, remember that you lose any contextual type information that using a custom exception type would give you.
A custom exception type gives you the ability to differentiate between the two conditions using general C# idioms, like so:
try
{
// do some database stuff
}
catch(KeyNotFoundException e)
{
// Here you know that it was more than likely caused by a Dictionary
// or some such collection
}
catch(DatabaseKeyNotFoundException e)
{
// Here you know that it was caused by a DB record not being found
}
Whichever you choose, just make sure you think about it, that it's consistent and logical. Don't just choose one because it's easier.
MSDN says yes* (if you consider a database table a collection) -
The exception that is thrown when the key specified for accessing an element in a collection does not match any key in the collection.
Why not just return false or some other indication that the value was not in the database?

Categories