study ASP.NET Core Razor Programming Series directory

study ASP.NET Core Razor Programming series one <http://www.cnblogs.com/chillsrc/p/8579777.html>

study ASP.NET Core Razor Programming Series 2 —— Add an entity
<http://www.cnblogs.com/chillsrc/p/8622439.html>

  study ASP.NET Core Razor Programming Series 3 —— Create data table and project basic page
<http://www.cnblogs.com/chillsrc/p/8651973.html>

study ASP.NET Core Razor Programming Series 4 ——Asp.Net Core Razor List template page
<http://www.cnblogs.com/chillsrc/p/8717199.html>

study ASP.NET Core Razor Programming Series 5 ——Asp.Net Core Razor New template page
<http://www.cnblogs.com/chillsrc/p/8778379.html>

study ASP.NET Core Razor Programming Series 6 —— database initialized
<http://www.cnblogs.com/chillsrc/p/8872303.html>

study ASP.NET Core Razor Programming Series 7 —— Modify list page
<http://www.cnblogs.com/chillsrc/p/8968398.html>

study ASP.NET Core Razor Programming Series 8 —— Concurrent processing
<http://www.cnblogs.com/chillsrc/p/8986512.html>

study ASP.NET Core Razor Programming Series 9 —— Add query function
<http://www.cnblogs.com/chillsrc/p/9025896.html>

  study ASP.NET Core Razor Programming Series 10 —— Add new field
<https://www.cnblogs.com/chillsrc/p/9077466.html>

study ASP.NET Core Razor Programming Series 11 —— Update new fields to database
<https://www.cnblogs.com/chillsrc/p/9111862.html>

study ASP.NET Core Razor Programming Series 12 —— Add check in page
<https://www.cnblogs.com/chillsrc/p/9178291.html>

study ASP.NET Core Razor Programming series 13 —— File upload function ( One )
<https://www.cnblogs.com/chillsrc/p/9243055.html>

study ASP.NET Core Razor Programming series 14 —— File upload function ( Two )
<https://www.cnblogs.com/chillsrc/p/9273635.html>

study ASP.NET Core Razor Programming Series 15 —— File upload function ( Three )
<https://www.cnblogs.com/chillsrc/p/9294202.html>

study ASP.NET Core Razor Programming Series 16 —— sort
<https://www.cnblogs.com/chillsrc/p/9415425.html>

  study ASP.NET Core Razor Programming series 17 —— grouping
<https://www.cnblogs.com/chillsrc/p/9517172.html>

 

 

     In the article ( study ASP.NET Core Razor Programming Series 8 —— Concurrent processing
<https://www.cnblogs.com/chillsrc/p/8986512.html>
) For concurrent errors in , We simply and brutally caught the exception , Then an exception is thrown . In this article, we look at two approaches to concurrency .

    There are three solutions to optimistic concurrency :

    1) You can track which properties the user has modified , And only the corresponding columns in the database are updated .

    under these circumstances , Data will not be lost . Two users updated different field contents ( for example : Book title and publishing house ). The next time someone browses a book , You'll see a change in the title and the publisher .
This update method can reduce the number of conflicts that cause data loss . This approach needs to be maintained in an important state , To keep track of all database values and current values , It increases the application complexity , May affect application performance . Generally not applicable to Web
application .

    2) It is possible to have a post commit user change override a previous user submitted change .

    This method is called “ Client first ” or “ Last priority ” programme . ( All values of the client take precedence over the values of the data store .) If you don't code any concurrent processing , Automatically “ Client first ”.

    3) You can prevent changes submitted by a later user from being updated in the database .

    This method , Error messages need to be displayed , Displays the current data and the data in the database , Allow user to modify again , And keep it . This is called “ Storage first ” programme . ( The data store value takes precedence over the value submitted by the client .)

One , Client optimization

    Let's take a look “ Client first ” programme . This method ensures that the submission of the latter user shall prevail , Overlay data in database .

    Optimistic concurrency allows concurrency conflicts to occur , And make correct response when concurrent conflict occurs .
for example , Administrator access to edit page with book information , take “Publishing” Change the field value to “ tsinghua university press ”.

1. first , We use Visual Studio
2017 open Books\Edit.cshmtl.cs file , to glance at OnPostAsync() method , The code is as follows . As shown in the figure below .
public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) {
return Page(); } _context.Attach(Book).State = EntityState.Modified; try { await
_context.SaveChangesAsync(); }catch (DbUpdateConcurrencyException) { if
(!_context.Book.Any(e => e.ID == Book.ID)) { return NotFound(); } else { throw;
} }return RedirectToPage("./Index"); }
2. stay Visual Studio
2017 Middle press F5 Running applications . Browsing book information in browser , And select a book information in the book list page . Let's assume that there are two users who want to edit this book information . First, the administrator , This book information has been modified “Publishing” Information for . As shown in the figure below .

 

3. Click on the administrator “Save” Before the button ,Test The user visited the same page , And will “ Date of publication ” Revised to “2018-01-08”. As shown in the figure below .

 

4.Test The user clicks first “ preservation ”, And in the browser's book information list page, we can see that his modified publication date data is saved to the database . As shown in the figure below .

 


5. here , Administrator Click “ edit ” On the page “ preservation ”, But on the page “ Date of publication ” still “2018-01-13”, according to “ Client optimization ” The rules will Test The user's modification is over written . As shown in the figure below .

 

 

 

Two , Storage first

 

    Let's take a look “ Storage first ” programme . This method ensures that the user does not override any changes when the alert is not received .

    First, let's look at three sets of values :

* “ Current value ” Is the value that the application is trying to write to the database .
* “ Original value ” Is the value initially retrieved from the database before any editing is made .
* “ Database values ” Is the value currently stored in the database .
    The normal way to handle concurrency conflicts is to :

     1) stay SaveChanges Period capture DbUpdateConcurrencyException.

    2) use DbUpdateConcurrencyException.Entries Prepare a new set of changes for the affected entities .

    3) Refresh the original value of the concurrent token to reflect the current value in the database .

    4) Try the process again , Until there is no conflict .

   The following example , Use timestamp as row level version number .

1. stay Visual Studio 2017 Of “ Solution Explorer ” Open it by double clicking with the left mouse button Models /Book.cs file ,
Yes User Entity add trace attribute RowVersion, And add Timestamp characteristic . The code is as follows :
using System; using System.Collections.Generic; using
System.ComponentModel.DataAnnotations;using System.Linq; using
System.Threading.Tasks;namespace RazorMvcBooks.Models { public class Book {
public int ID { get; set; } [Required] [StringLength(50, MinimumLength = 2)]
public string Name { get; set; } [Display(Name = " Date of publication ")]
[DataType(DataType.Date)]public DateTime ReleaseDate { get; set; } [Range(1,200
)] [DataType(DataType.Currency)]public decimal Price { get; set; } public string
Author {get; set; } [ Required] public string Publishing { get; set; }
[Timestamp]public byte[] RowVersion { get; set; } } }
 

2. stay Visual Studio 2017 Choose from “ menu >Nuget Package manager > package manager console ”, Then execute the following commands in turn from the package manager console that opens
Add-Migration RowVer Update-Database
3. stay SQL Server Management Studio View in Book surface . As shown in the figure below .

 

4. stay Visual Studio 2017 Of “ Solution Explorer ” Open it by double clicking with the left mouse button
Pages/Books/Edit.cshtml.cs file , Yes OnPostAsync The method was modified .Entity Framework Core Use contains raw
RowVersion Value of WHERE Clause generation SQL UPDATE command . If you don't get it UPDATE Command influence ( No rows have primitives RowVersion
value ), Will trigger DbUpdateConcurrencyException abnormal . The code is as follows :
public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) {
return Page(); } var updBook = _context.Book.AsNoTracking().Where(u => u.ID ==
Book.ID).First();// If null, Then the current user information has been delete if (updBook == null) { return
HandDeleteBook(); } _context.Attach(Book).State= EntityState.Modified; if (await
TryUpdateModelAsync<Book>( Book, "Book", s => s.Name, s =>s.Publishing, s =>
s.ReleaseDate, s => s.Price)) { try { await _context.SaveChangesAsync(); return
RedirectToPage("./Index"); } catch (DbUpdateConcurrencyException ex) { var
exceptionEntry = ex.Entries.Single(); var clientValues =
(Book)exceptionEntry.Entity;var databaseEntry =
exceptionEntry.GetDatabaseValues();if (databaseEntry == null) {
ModelState.AddModelError(string.Empty, " Save failed !. The current user information has been deleted "); return Page(); }
var dbValues = (Book)databaseEntry.ToObject(); setDbErrorMessage(dbValues,
clientValues, _context);// Using the RowVersion Value to the current entity object client interface RowVersion value .
The next time the user clicks “ preservation ” Time , Only concurrent errors that occurred after the last display of the edit page are captured . Book.RowVersion = (byte
[])dbValues.RowVersion;//ModelState With old RowVersion value , Therefore, it is necessary to use ModelState.Remove
sentence . stay Razor Page ,
// When both exist , Field's ModelState Value is better than model property value . ModelState.Remove("Book.RowVersion"); } }
return Page(); } private PageResult HandDeleteBook() { Book deletedDepartment =
new Book(); ModelState.AddModelError(string.Empty, " Save failed !. The current book information has been deleted !"); return
Page(); }
 


6. stay Edit.cshtml.cs file , add to setDbErrorMessage method . Add a custom error message for each column , When the database values in these columns are different from those on the client interface , Give the corresponding error message . The code is as follows :     

private void setDbErrorMessage(Book dbValues, Book clientValues, BookContext
context) {if (dbValues.Name != clientValues.Name) { ModelState.AddModelError("
Book.Name", $" Database values : {dbValues.Name}"); } if (dbValues.Publishing !=
clientValues.Publishing) { ModelState.AddModelError("Book.Publishing", $" Database values :
{dbValues.Publishing}"); } if (dbValues.ReleaseDate !=
clientValues.ReleaseDate) { ModelState.AddModelError("Book.ReleaseDate", $"
Database values : {dbValues.ReleaseDate}"); } if (dbValues.Price != clientValues.Price) {
ModelState.AddModelError("Book.Price", $" Database values : {dbValues.Price}"); }
ModelState.AddModelError(string.Empty," The book information record you are trying to edit has been modified by another user . The edit operation was canceled ," + "
The current value in the database is already displayed . If you still want to edit this record , Please click “ preservation ” Button ."); }
7. stay Visual Studio 2017 Of “ Solution Explorer ” Open it by double clicking with the left mouse button Pages/Books/Edit.cshtml file ,  <form
method="post"> Add hidden row version under tag . Must be added RowVersion, To send back the binding value .

    <input type="hidden" asp-for="Book.RowVersion" />

8. stay Visual Studio
2017 Middle press F5 Running applications . Use two browsers to open the same book information record for editing , At this time, the two browsers display the same book information . browser 1 Book information interface in . In the revision “Publishing” Data from “ tsinghua university press ” Revised as “ Machinery Industry Press ”, Then click “Save” Button . As shown in the figure below .

 

9. Click in the browser “ preservation ” after , The browser will automatically jump to the book information list page and see the modified “Publishing” The data is saved to the database . As shown in the figure below .

 

 

10. In the second browser , modify “ Date of publication ” Value of , from “2018-01-13” Change to “2018-01-08”. As shown in the figure below .

 

11. Then click “ Save” Button . At this time, the information on the client interface is different from the value in the database , So there will be an error message . As shown in the figure below .

 

  12. hold “Publishing” Revised as “ Machinery Industry Press ”, Click again “ preservation ”, Save the value entered in the second browser to the database .
Browser automatically jump to book information list , You can see the saved values . As shown in the figure below .

 

13. Of course, if you don't make any changes , Click Save again , It also saves the data on the current page to the database . As shown in the figure below .