Entity Framework concurrent processing, entityframework

Source: Internet
Author: User

Entity Framework concurrent processing, entityframework

Reference page:

Http://www.yuanjiaocheng.net/entity/entity-relations.html

Http://www.yuanjiaocheng.net/entity/entity-lifecycle.html

Http://www.yuanjiaocheng.net/entity/code-first.html

Http://www.yuanjiaocheng.net/entity/mode-first.html

Http://www.yuanjiaocheng.net/entity/database-first.html

What is concurrency?

Concurrency is divided into pessimistic concurrency and optimistic concurrency.

Pessimistic concurrencyFor example, if two users A and B log on to the system and modify A document, if A first changes the document, the system locks the document and B cannot open it, B can be modified only when A is completely exited.

Optimistic Concurrency: As shown in the preceding example, users A and B log on to the ECS instance at the same time. A is modifying the document while B is modifying it. If B saves its modifications after A is saved, the system detects that the document records in the database are inconsistent with that of B when B enters the database. B throws an exception during saving and the modification fails.

How to Control concurrency in EF?

Entity Framework does not support pessimistic concurrency, but supports optimistic concurrency.

To Concurrently process a table, add a Timestamp field to the table. Note that a table can have only one Timestamp field.

Data AnnotationsUse Timestamp to identify and set the concurrency control field. The field identified as Timestamp must be of the byte [] type.

public class Person    {        public int PersonId { get; set; }        public int SocialSecurityNumber { get; set; }        public string FirstName { get; set; }        public string LastName { get; set; }        1484643426        public byte[] RowVersion { get; set; }    }

Fluent APIIsRowVersion Method

modelBuilder.Entity<Person>().Property(p => p.RowVersion).IsRowVersion();

In the generated database, RowVersion is of the timestamp type.

Let's write a piece of code to test it:

Static void Main (string [] args) {var person = new Person {FirstName = "Rowan", LastName = "Miller", SocialSecurityNumber = 12345678}; // Add a record, save to database using (var con = new BreakAwayContext () {con. people. add (person); con. saveChanges ();} var firContext = new BreakAwayContext (); // obtain the first record and modify a field: The FirstName is modified. // var p1 = firContext is not saved first. people. firstOrDefault (); p1.FirstName = "Steven"; // create another Context, take the first record, modify the LastName field, and save using (var secContext = new BreakAwayContext ()) {var p2 = secContext. people. firstOrDefault (); p2.LastName = "Francis"; secContext. saveChanges ();} try {firContext. saveChanges (); Console. writeLine ("saved successfully");} catch (DbUpdateConcurrencyException ex) {Console. writeLine (ex. entries. first (). entity. getType (). name + "failed to save");} Console. read ();}

We have instantiated three DbContext above. The first one adds a record to the database, and the second one modifies the newly added record but does not save it, the third Context also retrieves and saves the newly added record, and then saves the second Context. The result fails to be saved.

We can see that our concurrency control has taken effect.

Analyze the SQL statements generated by EF:

exec sp_executesql N'update [dbo].[People]set [LastName] = @0where (([PersonId] = @1) and ([RowVersion] = @2))select [RowVersion]from [dbo].[People]where @@ROWCOUNT > 0 and [PersonId] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8)',@0=N'Francis',@1=1,@2=0x00000000000007D1

As you can see, it also uses RowVersion as the filter condition when getting the corresponding record. When the secContext in the preceding example is saved, the value of the RowVersion field in the database changes. Therefore, when the firContext is saved, the original RowVersion value is used. In this case, no corresponding record is obtained and an error is returned.

What if we only want to control the concurrency of a field? Don't worry, EF also has a solution.

Data AnnotationsIdentified by ConcurrencyCheck

 public class Person    {        public int PersonId { get; set; }        [ConcurrencyCheck]        public int SocialSecurityNumber { get; set; }        public string FirstName { get; set; }        public string LastName { get; set; }        public byte[] RowVersion { get; set; }    }

Fluent APIUse IsConcurrencyToken

modelBuilder.Entity<Person>().Property(p => p.SocialSecurityNumber).IsConcurrencyToken();

In the above Entity, we mark SocialSecurityNumber (Social Security number) as open concurrency, and also write a similar code to test it:

Static void Main (string [] args) {var person = new Person {FirstName = "Rowan", LastName = "Miller", SocialSecurityNumber = 12345678}; // Add a record, save to database using (var con = new BreakAwayContext () {con. people. add (person); con. saveChanges ();} var firContext = new BreakAwayContext (); // obtain the first record and modify the SocialSecurityNumber field. // do not save var p1 = firContext. people. firstOrDefault (); p1.SocialSecurityNumber = 123; // create another Context, take the first record, // modify the SocialSecurityNumber field and save using (var secContext = new BreakAwayContext ()) {var p2 = secContext. people. firstOrDefault (); p2.SocialSecurityNumber = 456; secContext. saveChanges ();} try {firContext. saveChanges (); Console. writeLine ("saved successfully");} catch (DbUpdateConcurrencyException ex) {Console. writeLine (ex. entries. first (). entity. getType (). name + "failed to save");} Console. read ();}

The running results are also failed to be saved, indicating that our concurrency control takes effect.

Analyze the SQL statement executed by EF:

exec sp_executesql N'update [dbo].[People]set [SocialSecurityNumber] = @0where (([PersonId] = @1) and ([SocialSecurityNumber] = @2))',N'@0 int,@1 int,@2 int',@0=123,@1=1,@2=12345678

We can see that EF uses the SocialSecurityNumber column to be concurrently controlled as a filter condition, so that the value of SocialSecurityNumber in the database will change during the firContext saving, failed to update because the corresponding record cannot be obtained.

Add: For EDMX, how does one set the field to Concurrency. You can right-click the corresponding field and choose Properties. There isConcurrency Mode, You chooseFixedYou can.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.