首页 > 解决方案 > 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(...))

可能与不当使用异步函数有关吗?也许是因为我没有返回更新的会员,因此下次我执行更新时,我会发送一个现在过期的会员?

另外:我找到了这个答案,但这对我来说毫无意义

谢谢!

标签: c#entity-frameworkasynchronous.net-coreentity-framework-core

解决方案


我使用这样的通用代码进行更新:

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;
 }
}

推荐阅读