文章出處

好久沒更新EF這個系列了,現在又重新開始。

這次學習,開放式并發。首先拿出數據庫腳本:

說明一下,這個數據庫腳本是之前的章節中稍作修改的:

USE [SchoolDB]
GO

/****** Object:  Table [dbo].[Student]    Script Date: 11/30/2015 21:42:07 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Student](
    [StudentID] [INT] NOT NULL,
    [StudentName] [NVARCHAR](100) NULL,
    [StandardID] [INT] NULL,
    [RowVersion] [TIMESTAMP] NOT NULL,
 CONSTRAINT [PK__Student__32C52A7903317E3D] PRIMARY KEY CLUSTERED 
(
    [StudentID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Student]  WITH CHECK ADD  CONSTRAINT [FK__Student__Standar__0519C6AF] FOREIGN KEY([StandardID])
REFERENCES [dbo].[Standard] ([StandardID])
GO

ALTER TABLE [dbo].[Student] CHECK CONSTRAINT [FK__Student__Standar__0519C6AF]
GO

然后,我們在數據模型中更新一下模型EDMx

 

 

可以看到Student模型上面,出現了Rowversion字段,我們選中它,右鍵-->屬性,修改并發模式為Fixed。

EF will now include a RowVersion column in the where clause, whenever you do an update operation and if the rowversion value is different than in the where clause then it will throwDbUpdateConcurrencyExection.

下面開始實踐:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFTutorials
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu1 = null;
            Student stu2 = null;

            using (var db = new SchoolDBEntities1())
            {
                db.Configuration.ProxyCreationEnabled = false;

                stu1 = db.Students.Where(s => s.StudentID == 1).FirstOrDefault();
            }

            using (var db = new SchoolDBEntities1())
            {
                db.Configuration.ProxyCreationEnabled = false;

                stu2 = db.Students.Where(s => s.StudentID == 1).FirstOrDefault();
            }

            stu1.StudentName = "Edit Stuent1";
            stu2.StudentName = "Edit Stuent2";


            using (var db = new SchoolDBEntities1())
            {
                try
                {
                    db.Entry(stu1).State = EntityState.Modified;
                    db.SaveChanges();
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    Console.WriteLine("Optimistic Concurrency exception occured");
                }
               
            }

            using (var db = new SchoolDBEntities1())
            {
                try
                {
                    db.Entry(stu2).State = EntityState.Modified;
                    db.SaveChanges();
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    Console.WriteLine("Optimistic Concurrency exception occured");
                }
                
            }



        }
    }
}

執行完stu1那個查詢之后:

SELECT TOP (1)
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent1].[StandardID] AS [StandardID],
[Extent1].[RowVersion] AS [RowVersion]
FROM [dbo].[Student] AS [Extent1]
WHERE 1 = [Extent1].[StudentID]

執行完,stu1的保存修改之后:

exec sp_executesql N'UPDATE [dbo].[Student]
SET [StudentName] = @0, [StandardID] = NULL
WHERE (([StudentID] = @1) AND ([RowVersion] = @2))
SELECT [RowVersion]
FROM [dbo].[Student]
WHERE @@ROWCOUNT > 0 AND [StudentID] = @1',N'@0 nvarchar(100),@1 int,@2 binary(8)',@0=N'Edit Stuent1',@1=1,@2=0x00000000000007D6

可以肯定的得出,在這里會出錯,也就是并發。

Concurrency in Code-First:

You can create a timestamp property in code-first by usng [Timestamp] attribute. Make sure that the property type is byte[] because timestamp is binary in C#.

    
        [Timestamp]
        public byte[] RowVersion { get; set; }
        

EF includes a property in the where clause, during the update operation, if the property is marked with the Timestamp attribute.

You can resolve concurrency exceptions many ways. Visit msdn for detailed information on how to resolve optimistic concurrency.

Download sample project for the basic tutorials.

 

 

今天有點晚了,明天來繼續,怎么解決這個并發。哈哈!!


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()