Cha*_*ith 44 entity-framework-6 entity-framework-core .net-core
在实体框架工作核心中更新数据库表数据的最佳方法是什么?
我们可以在EF6上使用哪些改进功能?
H. *_*rzl 56
要使用Entity Framework Core更新实体,这是一个逻辑过程:
DbContext类创建实例Update()方法DbContext:
开始跟踪处于Modified状态的给定实体,以便在
SaveChanges()调用时在数据库中更新它.
Update方法不保存数据库中的更改; 相反,它为DbContext实例中的条目设置状态.
因此,我们可以Update()在保存数据库更改之前调用方法.
我会假设一些对象定义来回答你的问题:
数据库名称是Store
表名是Product
产品类定义:
public class Product
{
public int? ProductID { get; set; }
public string ProductName { get; set; }
public string Description { get; set; }
public decimal? UnitPrice { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
DbContext类定义:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
更新实体的逻辑:
using (var context = new StoreDbContext())
{
// Retrieve entity by id
// Answer for question #1
var entity = context.Products.FirstOrDefault(item => item.ProductID == id);
// Validate entity is not null
if (entity != null)
{
// Answer for question #2
// Make changes on entity
entity.UnitPrice = 49.99m;
entity.Description = "Collector's edition";
// Update entity in DbSet
context.Products.Update(entity);
// Save changes in database
context.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
如果这有用,请告诉我
Sha*_*dam 38
public async Task<bool> Update(MyObject item)
{
Context.Entry(await Context.MyDbSet.FirstOrDefaultAsync(x => x.Id == item.Id)).CurrentValues.SetValues(item);
return (await Context.SaveChangesAsync()) > 0;
}
Run Code Online (Sandbox Code Playgroud)
Ehs*_*edi 34
根据微软的文档:
read-first方法需要额外的数据库读取,并且可能导致更复杂的代码以处理并发冲突
但是,您应该知道在DbContext上使用Update方法会将所有字段标记为已修改,并将在查询中包含所有字段.如果要更新字段子集,则应使用Attach方法,然后将所需字段标记为手动修改.
context.Attach(person);
context.Entry(person).Property("Name").IsModified = true;
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
The*_*ist 22
假设我们有一个实体Student,AppDbContext如下所示。
class Student
{
public int Id { get; set; }
public string Name { get; set; } = default!;
public int Age { get; set; }
}
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> opts) : base(opts) { }
public DbSet<Student> Students { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
CurrentValues只能对跟踪实体 ( found) 起作用。Modified。TEntity当使用类型参数而不是固定类型时,自动属性映射非常有用Student。async Task Edit_A(int id, Student incoming, AppDbContext db)
{
if (await db.Students.FindAsync(id) is Student found)
{
db.Entry(found).CurrentValues.SetValues(incoming);
await db.SaveChangesAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
found)。Modified。async Task Edit_B(int id, Student incoming, AppDbContext db)
{
if (await db.Students.FindAsync(id) is Student found)
{
found.Name = incoming.Name;
found.Age = incoming.Age;
await db.SaveChangesAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
Update()仅适用于未跟踪的实体 ( incoming) 并使其被跟踪。found调用前取消跟踪Update(incoming)是强制性的,因为使用给定的主键只能跟踪一个实体。Modified。它的效率较低。async Task Edit_C(int id, Student incoming, AppDbContext db)
{
if (await db.Students.FindAsync(id) is Student found)
{
db.Students.Entry(found).State = EntityState.Detached;
db.Students.Update(incoming);
await db.SaveChangesAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
incoming) 并使其被跟踪。取消跟踪found是强制性的,因为只能使用给定的主键跟踪一个实体。Modified。它的效率较低。async Task Edit_D(int id, Student incoming, AppDbContext db)
{
if (await db.Students.FindAsync(id) is Student found)
{
db.Students.Entry(found).State = EntityState.Detached;
db.Students.Entry(incoming).State = EntityState.Modified;
await db.SaveChangesAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
incoming) 并使其被跟踪。取消跟踪found是强制性的,因为只能使用给定的主键跟踪一个实体。IsModified=true才会更新。如果标记IsModified=true未更改的属性,效率会降低。async Task Edit_E(int id, Student incoming, AppDbContext db)
{
if (await db.Students.FindAsync(id) is Student found)
{
db.Students.Entry(found).State = EntityState.Detached;
db.Students.Entry(incoming).Property(s => s.Name).IsModified = true;
db.Students.Entry(incoming).Property(s => s.Age).IsModified = true;
await db.SaveChangesAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
我将其设置为社区 Wiki,您可以随意编辑。
Mel*_*per 10
超级简单
using (var dbContext = new DbContextBuilder().BuildDbContext())
{
dbContext.Update(entity);
await dbContext.SaveChangesAsync();
}
Run Code Online (Sandbox Code Playgroud)
Microsoft Docs为我们提供了两种方法。
推荐的HttpPost 编辑代码:读取和更新
这与我们在以前版本的实体框架中使用的旧方法相同。这就是微软为我们推荐的。
好处
Modified在由表单输入更改的字段上设置标志。替代HttpPost 编辑代码:创建并附加
另一种方法是将模型绑定器创建的实体附加到 EF 上下文并将其标记为已修改。
正如另一个答案中提到的,读取优先方法需要额外的数据库读取,并且可能会导致处理并发冲突的代码更加复杂。
| 归档时间: |
|
| 查看次数: |
65204 次 |
| 最近记录: |