在实体框架工作核心中更新数据库表数据的最佳方法是什么?
我们可以在EF6上使用哪些改进功能?
答案 0 :(得分:37)
要使用Entity Framework Core更新实体,这是一个逻辑过程:
AddDialog
class DbContext
中的 Update()
方法:
开始跟踪处于已修改状态的给定实体,以便在调用
DbContext
时在数据库中对其进行更新。
更新方法不保存数据库中的更改;相反,它为DbContext实例中的条目设置状态。
因此,我们可以先调用SaveChanges()
方法保存数据库中的更改。
我会假设一些对象定义来回答你的问题:
数据库名称为Store
表名是产品
产品类定义:
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)
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)
查看所有答案后,我想我会添加两个简单的选项
如果您已经使用启用了跟踪功能的FirstOrDefault()访问记录(不使用.AsNoTracking()函数,因为它将禁用跟踪功能)并更新了某些字段,那么您只需调用context.SaveChanges()
在其他情况下,您要么是使用HtppPost将实体发布到服务器上,要么是由于某种原因禁用了跟踪,那么您应该在context.SaveChanges()之前调用context.Update(entityName)
第一个选项将仅更新您更改的字段,而第二个选项将更新数据库中的所有字段,即使实际上未更新任何字段值:)
答案 5 :(得分:0)
Microsoft Docs为我们提供了两种方法。
推荐 HttpPost编辑代码:读取和更新
这与我们在先前版本的Entity Framework中使用的旧方法相同。这就是Microsoft向我们推荐的。
优势
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"; });