c# - C# - Entity Framework Core - 数据库操作预计会影响 1 行,但实际上影响了 0 行
问题描述
我正在使用 Entity Framework 与 SQL Server 数据库交互的 ASP.NET Core 3.1 中构建一个 n 层 Web 应用程序。一切正常,除了两次更新实体而不在两个请求之间刷新。
所以我第一次从数据库中读取实体并更新它时,它工作得很好。当我尝试在之后立即更新实体时,出现以下异常:
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException:数据库操作预计会影响 1 行,但实际上影响了 0 行。
自加载实体以来,数据可能已被修改或删除...
我将通用存储库模式与异步代码结合使用。
我的代码概述:
GenericRepository.cs:
public class Repository<T> : IRepository<T> where T : class
{
protected readonly DataContext _context;
protected DbSet<T> _entities;
public Repository(DataContext context)
{
this._context = context;
_entities = context.Set<T>();
}
}
MemberRepository.cs:
public class MemberRepository : Repository<Member>, IMemberRepository
{
public MemberRepository(DataContext context) : base(context)
{
//
}
public async override Task<Member> SelectByIdAsync(int id)
{
return await this._entities
.Where(m => m.Id == id)
.Include(m => m.Addresses)
.Include(m => m.MemberHobbies)
.Include(m => m.Car)
.Include(m => m.EmailAddresses)
.FirstOrDefaultAsync();
//return await this._context.Members.Where(m => m.Id == id).Include(m => m.Addresses).Include(m => m.MemberHobbies).Include(m => m.Car).Include(m => m.EmailAddresses).FirstOrDefaultAsync();
}
public async override Task UpdateAsync(Member member)
{
this._context.Members.Update(member);
//this._context.Set<Member>().Update(member);
await this._context.SaveChangesAsync();
}
}
启动.cs:
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
services.AddScoped<IMemberRepository, MemberRepository>();
我试图改变我阅读或更新我的实体的方式(见注释掉的行),但那些给出了相同的结果。另外:我还有其他可以完美运行的实体,唯一的区别是 Member 类有多个外键(参见 .Include(...))
可能与不当使用异步函数有关吗?也许是因为我没有返回更新的会员,因此下次我执行更新时,我会发送一个现在过期的会员?
另外:我找到了这个答案,但这对我来说毫无意义
谢谢!
解决方案
我使用这样的通用代码进行更新:
public virtual async Task<T> UpdateAsync(T t)
{
if (t == null) return null;
T exist;
try
{
exist = await Context.Set<T>().FindAsync(t.Id);
if (exist == null)
{
t.ErrorMessage = "Can't find item to update";
return t;
}
Context.Entry(exist).CurrentValues.SetValues(t);
var result = await Context.SaveChangesAsync();
if (result == 0) t.ErrorMessage = "Can't saved item";
}
catch (Exception ex)
{
t.ErrorMessage = ex.Message;
return t;
}
return exist;
}
或者您可以尝试此代码的成员类:
public async Task UpdateAsync(Member member)
{
try
{
var exist = await _context.Members.Where(i.Id=member.Id).FirstOrDefaultAsync();
if (exist == null) ....errorMessage = "Can't find item to update";
Context.Entry(exist).CurrentValues.SetValues(member);
var result = await Context.SaveChangesAsync();
if (result == 0) ....errorMessage = "Can't save item";
}
catch (Exception ex)
{
...errorMessage = ex.Message;
}
}
推荐阅读
- javascript - Sequelize 中的异步 getter/setter 作为属性的一部分
- c# - 在网络位置的程序中打开套接字时出错
- java - 主类完成后执行器线程继续运行
- java - Camunda 在启动期间在本地 oracle db 上引发错误
- java - 将箭头图标更改为汉堡图标
- react-native - 在运行 e2e 测试之前如何不重建反应原生应用程序?
- php - Mysql如何推断数据并放入数组?
- python - 如何使用 Folium 在“鼠标悬停”上突出显示世界国家边界?
- java - 如何在 Java 中同时录制麦克风和扬声器的音频?
- html - 服务器返回 HTML 而不是预期的 JSON 响应