如何使用实体框架核心更新记录?

时间:2017-10-10 02:32:01

标签: entity-framework-6 .net-core entity-framework-core

在实体框架工作核心中更新数据库表数据的最佳方法是什么?

  1. 检索表格行,进行更改并保存
  2. 在数据库上下文中使用关键字更新,并处理项目不存在的例外
  3. 我们可以在EF6上使用哪些改进功能?

7 个答案:

答案 0 :(得分:37)

要使用Entity Framework Core更新实体,这是一个逻辑过程:

  1. AddDialog class
  2. 创建实例
  3. 按键检索实体
  4. 对实体的属性进行更改
  5. 保存更改
  6. DbContext中的

    Update()方法:

      

    开始跟踪处于已修改状态的给定实体,以便在调用DbContext时在数据库中对其进行更新。

    更新方法不保存数据库中的更改;相反,它为DbContext实例中的条目设置状态。

    因此,我们可以先调用SaveChanges()方法保存数据库中的更改。

    我会假设一些对象定义来回答你的问题:

    1. 数据库名称为Store

    2. 表名是产品

    3. 产品类定义:

      Update()

      DbContext类定义:

      public class Product
      {
          public int? ProductID { get; set; }
      
          public string ProductName { get; set; }
      
          public string Description { get; set; }
      
          public decimal? UnitPrice { get; set; }
      }
      

      更新实体的逻辑:

      public class StoreDbContext : DbContext
      {
          public DbSet<Product> Products { get; set; }
      
          protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
          {
              optionsBuilder.UseSqlServer("Your Connection String");
      
              base.OnConfiguring(optionsBuilder);
          }
      
          protected override void OnModelCreating(ModelBuilder modelBuilder)
          {
              modelBuilder.Entity<Order>(entity =>
              {
                  // Set key for entity
                  entity.HasKey(p => p.ProductID);
              });
      
              base.OnModelCreating(modelBuilder);
          }
      }
      

      请告诉我这是否有用

答案 1 :(得分:19)

根据Microsoft docs

  

read-first方法需要额外的数据库读取,并且可能导致更复杂的代码来处理并发冲突

但是,您应该知道在DbContext上使用Update方法会将所有字段标记为 modified ,并将在查询中包含所有字段。如果要更新字段子集,则应使用Attach方法,然后手动将所需字段标记为 modified

    context.Attach(person);
    context.Entry(person).Property("Name").IsModified = true;
    context.SaveChanges();

答案 2 :(得分:7)

超级简单

using (var dbContext = new DbContextBuilder().BuildDbContext())
{
    dbContext.Update(entity);
    await dbContext.SaveChangesAsync();
}

答案 3 :(得分:6)

实际上,最佳实践是

from descriptors import cachedclassproperty

class MyClass:
    @cachedclassproperty
    def approx_pi(cls):
        return 22 / 7

答案 4 :(得分:2)

查看所有答案后,我想我会添加两个简单的选项

  1. 如果您已经使用启用了跟踪功能的FirstOrDefault()访问记录(不使用.AsNoTracking()函数,因为它将禁用跟踪功能)并更新了某些字段,那么您只需调用context.SaveChanges()

  2. 在其他情况下,您要么是使用HtppPost将实体发布到服务器上,要么是由于某种原因禁用了跟踪,那么您应该在context.SaveChanges()之前调用context.Update(entityName)

第一个选项将仅更新您更改的字段,而第二个选项将更新数据库中的所有字段,即使实际上未更新任何字段值:)

答案 5 :(得分:0)

Microsoft Docs为我们提供了两种方法。

  

推荐 HttpPost编辑代码:读取和更新

这与我们在先前版本的Entity Framework中使用的旧方法相同。这就是Microsoft向我们推荐的。

优势

  • 防止overposting
  • EFs自动更改跟踪在通过表单输入更改的字段上设置Modified标志。
  

替代 HttpPost编辑代码:创建并附加

另一种方法是将由模型绑定器创建的实体附加到EF上下文并将其标记为已修改。

如另一个答案中所述,先读方法需要额外的数据库读取,并且可能导致用于处理并发冲突的代码更加复杂。

答案 6 :(得分:0)

更通用的方法

为简化此方法,使用了“ id”界面

public interface IGuidKey
{
    Guid Id { get; set; }
}

辅助方法

    public static void Modify<T>(this DbSet<T> set, Guid id, Action<T> func)
        where T : class, IGuidKey, new()
    {
        var target = new T
        {
            Id = id
        };
        var entry = set.Attach(target);
        func(target);
        foreach (var property in entry.Properties)
        {
            var original = property.OriginalValue;
            var current = property.CurrentValue;

            if (ReferenceEquals(original, current))
            {
                continue;
            }

            if (original == null)
            {
                property.IsModified = true;
                continue;
            }

            var propertyIsModified = !original.Equals(current);
            property.IsModified = propertyIsModified;
        }
    }

用法

dbContext.Operations.Modify(id, x => { x.Title = "aaa"; });