[C#.NET][Entity Framework] DbContextTransaction @ EF6

[C#.NET][Entity Framework] DbContextTransaction @ EF6

在 ADO.NET 裡的交易機制,在EF6的邏輯基本上一樣,

DbContextTransaction 類別,提供 Commit  認可基礎存放區交易,Rollback 回復基礎存放區交易,兩個方法,

也就是說交易成功調用 Commit,失敗則調用Rollback

 

假設當我需要將一筆資料同時寫到兩個不同的地方,這時就可以利用 DbContextTransaction 類別 來決定要 Commit,還是Rollback

下面的例子,我故意創建相同的 Id(Primary Key),誘發 DbUpdateException 例外,例外發生則 Rollback


{
    using (var localDbContext = new LocalDbContext())
    using (var mySqlDbContext = new MySqlDbContext())
    using (var transaction1 = localDbContext.Database.BeginTransaction())
    using (var transaction2 = mySqlDbContext.Database.BeginTransaction())
    {
        localDbContext.Members.Add(new Member() { Id = 1, Name = "余小章" });
        mySqlDbContext.Members.Add(new Member() { Id = 1, Name = "余小章" });
        mySqlDbContext.Members.Add(new Member() { Id = 1, Name = "余小章" });

        try
        {
            var localResult = localDbContext.SaveChanges();
            var mySqlResult = mySqlDbContext.SaveChanges();
            if (localResult == 0 || mySqlResult == 0)
            {
                throw new DbUpdateException();
            }
            transaction1.Commit();
            transaction2.Commit();
            MessageBox.Show("OK");
        }
        catch (DbUpdateException)
        {
            transaction1.Rollback();
            transaction2.Rollback();
            MessageBox.Show("RollBack");
        }
    }
}

 

這樣一來就能確保雙方資訊一致性,

假設,一次有大量資料需要更新,也可以用它來確保,資料都被全部寫入。

 

 


元件版本


<packages>
  <package id="EntityFramework" version="6.0.0" targetFramework="net45" />
  <package id="MySql.Data" version="6.8.3" targetFramework="net45" />
  <package id="MySql.Data.Entities" version="6.8.3.0" targetFramework="net45" />
</packages>

 

組態檔


<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6"></provider>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
  <system.data>
  </system.data>
  <connectionStrings>
    <add name="mySql" providerName="MySql.Data.MySqlClient" connectionString="server=localhost; user id=your id; password=your password;database=demo; port=3306" />
    <add name="localDb" providerName="System.Data.SqlClient" connectionString="Data Source=(localdb)\v11.0;Initial Catalog=demo;Integrated Security=True" />
  </connectionStrings>
</configuration>

完整程式碼


public partial class Member
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }

    public string Name { get; set; }

    public string Phone { get; set; }
}

[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class MySqlDbContext : DbContext
{
    public DbSet<Member> Members { get; set; }

    public MySqlDbContext(string connextStringName)
        : base(connextStringName)
    {
    }

    public MySqlDbContext()
        : base("mySql")
    {
    }
}

public class LocalDbContext : DbContext
{
    public DbSet<Member> Members { get; set; }

    public LocalDbContext()
        : base("localDb")
    {
    }
}

 


在實做這個情境時發現了奇妙的現象

當我先實體化MySQL時,LocalDb居然會套用MySql.Data.MySqlClient…

image

 

反過來,就不會有這個現象

image

 

但是,資料庫不存在的時候會跳出,Specified key was too long; max key length is 767 bytes 例外訊息

image

 

猜測是 MySQL 的 EF 元件有問題,各別單獨運作(不同的Method區塊),則沒有任何問題

 


文章出自:http://www.dotblogs.com.tw/yc421206/archive/2014/03/20/144457.aspx

文章參考:http://msdn.microsoft.com/en-us/data/dn456843

 

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo