entity framework mysql provider_Entity Framework with MySQL Provider 更新行数为0的Bug

在使用MySQL作为Entity Framework的提供者时,可能会遇到更新、插入或删除影响行数为0的错误。这通常是由于MySQL和SQL Server处理机制的差异。通过在SavingChanges事件中检查并刷新未更改的实体,或者在DbContext的ValidateEntity方法中调整状态,可以避免这种错误。设置MySQL连接字符串中的Use Affected Rows为true也是一种解决方案。
摘要由CSDN通过智能技术生成

本文将很容易解决的问题搞复杂了,多数情况下将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 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: }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值