HTML5技术

EntityFramework Core问题处理集锦(一) - Jeffcky

字号+ 作者:H5之家 来源:H5之家 2017-08-07 11:00 我要评论( )

前言 和大家脱离了一段时间,有时候总想着时间挤挤总是会有的,但是并非人愿,后面会借助周末的时间来打理博客,如有问题可以在周末私信我或者加我QQ皆可,欢迎和大家一起探讨,本节我们来讨论EF Core中的一些问题后面陆陆续续会将EF Core中需要注意的地方补

前言

和大家脱离了一段时间,有时候总想着时间挤挤总是会有的,但是并非人愿,后面会借助周末的时间来打理博客,如有问题可以在周末私信我或者加我QQ皆可,欢迎和大家一起探讨,本节我们来讨论EF Core中的一些问题后面陆陆续续会将EF Core中需要注意的地方补充上来,有些是我一直以来比较疏忽的地方,不喜勿喷。用在实际项目中的时候才发现和平时所学有很大差异,靠着项目才能检验出真理。

EntityFramework Core问题集锦 更新单个实体

更新单个实体的方式有两种:

(1)查询出实体进行赋值更新

说的更专业一点则是已被跟踪的实体进行赋值更新,此时实体已被快照,此时进行更新时只需要调用SaveChanges或者SaveChangesAsync,当已赋值属性与快照中值不同时,此时调用SaveChangesAsync或者SaveChanges方法时会将此属性的状态即(IsModified)修改为True,否则为False。代码大概如下:

public async Task<bool> UpdateStatus(int id, byte status) { var blog = _efCoreContext.Blogs.Find(id); blog.Status = status; var effectRows = await _efCoreContext.SaveChangesAsync(CancellationToken.None); if (effectRows > 0) { return true; } return false; }

但是如上又带来一个问题,我们通过影响行数来获取是否更新成功,如果想更新某一列,但是此列的值未进行改变,此时与快照中的值一致,则受影响行数为0,结果返回的更新失败,如下所示:

在这种情况就需要一个扩展方法来显式指定更新属性即使值未发生改变也将其属性状态IsModified修改为True,这样才不会导致值未改变但是更新失败的情况,即如下:

_efCoreContext.Entry(blog).Property(d => d.Status).IsModified = true;

(2)未查询出实体进行赋值更新。

当此实体未进行查询,此时需要调用Update来将此实体状态中所有属性的IsModified修改为True,此时代码大概如下:

public async Task<bool> UpdateStatus(Blog blog) { _efCoreContext.Blogs.Update(blog); var effectRows = await _efCoreContext.SaveChangesAsync(CancellationToken.None); if (effectRows > 0) { return true; } return false; }

也就是说如果是明确实体所有属性都会更改则可以利用Update方法来更新所有属性,否则不需要更新的属性比如常见场景:数据库中表中数据创建时间下次进行更新时是不需要更新,如若调用Update方法,如果对创建时间赋值会进行覆盖,未赋值则会显示DateTime默认时间。

批量更新之表达式树

批量更新的场景大有,在我们项目中选择多个产品将产品的状态更新为下架状态,下面我们来还原场景。创建批量更新接口,此时数据库中数据如下:

Task<bool> UpdateStatus(int[] ids);

我们将Blog中状态中为0的行更新为1,此时接口则如下:

public async Task<bool> UpdateStatus(int[] ids) { var blogs = _efCoreContext.Blogs.Where(d => ids.Contains(d.Id)); blogs.Select(b => new Blog() { Id = b.Id, Status = 1 }).ToList(); if (await _efCoreContext.SaveChangesAsync(CancellationToken.None) > 0) { return true; } return false; }

此时更新肯定不能正确更新,其原因不必多讲,由于是更新集合中的指定属性,此时我写了关于单个和集合更新指定属性的扩展方法,如下:

EfCoreUpdateExe { Update<T>(this EFCoreContext context, T entity, params Expression<Func<T, object>>[] properties) where T : class, new() { var dbEntityEntry = context.Entry(entity); if (properties.Any()) { foreach (var property in properties) { dbEntityEntry.Property(property).IsModified = true; } } else { foreach (var rawProperty in dbEntityEntry.Entity.GetType().GetTypeInfo().DeclaredProperties) { var originalValue = dbEntityEntry.Property(rawProperty.Name).OriginalValue; var currentValue = dbEntityEntry.Property(rawProperty.Name).CurrentValue; foreach (var property in properties) { if (originalValue != null && !originalValue.Equals(currentValue)) dbEntityEntry.Property(property).IsModified = true; } } } } UpdateRange<TEntity>(this EFCoreContext context, IEnumerable<TEntity> entities, bool isNoTracking = true, params Expression<Func<TEntity, object>>[] properties) where TEntity : class, new() { foreach (var entity in entities) { var dbEntityEntry = context.Entry(entity); (!isNoTracking) { dbEntityEntry.State = EntityState.Unchanged; } if (properties.Any()) { foreach (var property in properties) { dbEntityEntry.Property(property).IsModified = true; } } else { foreach (var rawProperty in dbEntityEntry.Entity.GetType().GetTypeInfo().DeclaredProperties) { var originalValue = dbEntityEntry.Property(rawProperty.Name).OriginalValue; var currentValue = dbEntityEntry.Property(rawProperty.Name).CurrentValue; foreach (var property in properties) { if (originalValue != null && !originalValue.Equals(currentValue)) dbEntityEntry.Property(property).IsModified = true; } } } } } }

然后代码更新代码修改如下:

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 带你快速进入.net core的世界 - 农码一生

    带你快速进入.net core的世界 - 农码一生

    2017-08-07 10:02

  • 解决百度富文本编辑器 UEditor 插入视频后没有路径的问题 - 我们都是程序猿

    解决百度富文本编辑器 UEditor 插入视频后没有路径的问题 - 我们都是

    2017-08-02 13:00

  • Entity Framework Core 执行SQL语句和存储过程 - Sweet-Tang

    Entity Framework Core 执行SQL语句和存储过程 - Sweet-Tang

    2017-08-02 08:00

  • .NET Core 成都线下面基会拉开序幕 - Savorboard

    .NET Core 成都线下面基会拉开序幕 - Savorboard

    2017-08-01 10:02

网友点评
t