Entity Framework with MySQL Provider 更新行數為0的Bug

來源:互聯網
上載者:User

本文將很容易解決的問題搞複雜了,多數情況下將MySql連接字串中的Use Affected Rows參數設定為true即可。

2012-06-17 作者注。

 

在使用MySQL資料庫來做為Entity Framework的Provider時,有時會遇到如下問題:

儲存區更新、插入或刪除語句影響到了意外的行數(0)。實體在載入後可能被修改或刪除。重新整理 ObjectStateManager 項。

問題產生的情境可能為:

通常會遇到這樣的問題,我們開啟編輯介面,然後不更改任何內容,然後點儲存,基本流程為

   1: var detail=db.Table.FirstOrDefault(c=>c.id==1);

   2: detail.Content=model.Content;

   3: db.SaveChanges();

因為我們沒有更改任何內容,所以更改前與更改後的內容是一致的,這時會報出以上錯誤

其原因是因為MySQL與SQLServer的處理機制不同,如果更新內容與資料庫的一致,SQLServer仍然會返回受影響行數為1,但是MySQL則會認為受影響行數為0。

而Entity Framework應該是預設以SQLServer的為準,所以認為如果更新了,但是返回受影響條數為0,則認為是更新不正確

我們處理這個問題有很多方法 ,最笨的應該是在賦值前進行判斷,detail.Content是否與model.Content相等,如果相等就不進行賦值。

不過因為EntityFramework是在我們對屬性賦值時更新了此屬性的State使之標識為Modified或Deleted等 狀態,所以我們是可以有更方便的方法來控制這些更新的。

我們可以使用EntityFramework的Context中的SavingChanges這個事件在SaveChanges之前做一些處理:

其基本原理為

if(當前實體已經修改 && 所有屬性更改後的值與更改前的值相同){

使之不更新

}

我具體代碼實現如下

   1: public class EntityFrameworkFix

   2:     {

   3:         public static void SavingChanges(object sender, EventArgs e)

   4:         {

   5:             var context = sender as ObjectContext;

   6:             if (context == null) return;

   7:             var updatedEntites = context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified);

   8:  

   9:             foreach (var ose in updatedEntites)

  10:             {

  11:                 var props = ose.GetModifiedProperties().ToList();

  12:                 int modifyCount = 0;

  13:                 int propCount = props.Count();

  14:                 for (int i = 0; i < propCount; i++)

  15:                 {

  16:                     var prop = props[i];

  17:                     var index = ose.OriginalValues.GetOrdinal(prop);

  18:                     if (ose.OriginalValues.GetValue(index).Equals(ose.CurrentValues.GetValue(index)))

  19:                     {

  20:                         modifyCount++;

  21:                     }

  22:                 }

  23:                 if (modifyCount == propCount)

  24:                 {

  25:                     context.Refresh(RefreshMode.StoreWins, ose.Entity);

  26:                 }

  27:             }

  28:         }

  29:     }

然後我們在我們聲明Context時添加如下事件

   1: db.SavingChanges += EntityFrameworkFix.SavingChanges;

這樣就可以不執行那些賦值了,但值沒有變化的Update。

另外,前些天EntityFramework4.1也發布了,但是因為EntityFramework4.1中不再支援SavingChanges所以我們要使用其它方法 來支援,我們可以在DbContext中override ValidateEntity方法來實現這一過程

   1: public partial class MyEntities : DbContext

   2: {

   3:     protected override System.Data.Entity.Validation.DbEntityValidationResult ValidateEntity(System.Data.Entity.Infrastructure.DbEntityEntry entityEntry, System.Collections.Generic.IDictionary<object, object> items)

   4:     {

   5:         int wrongCount = 0;

   6:         int allCount = 0;

   7:         if(entityEntry.State== System.Data.EntityState.Modified)

   8:         {

   9:             foreach(var name in entityEntry.OriginalValues.PropertyNames)

  10:             {

  11:                 var prop = entityEntry.Property(name);

  12:                 if (prop.IsModified)

  13:                 {

  14:                     allCount++;

  15:                     if (prop.OriginalValue.Equals(prop.CurrentValue))

  16:                         wrongCount++;

  17:                 }

  18:  

  19:             }

  20:             if (wrongCount == allCount)

  21:                 entityEntry.State = System.Data.EntityState.Unchanged;

  22:         }

  23:         return base.ValidateEntity(entityEntry, items);

  24:     }

  25: }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.