简体   繁体   English

实体框架通用存储库模式异步添加方法和保存

[英]Entity Framework Generic Repository Pattern Async Add Method with Save

I have a base repository class called Repository.我有一个名为 Repository 的基础存储库 class。 Can anyone explain me how should I make methods in this class async?谁能解释我应该如何在这个 class 异步中创建方法?

public abstract class Repository<TEntity> : IRepository<TEntity> where TEntity : Entity
{
    private readonly DbContext _context;
    private readonly DbSet<TEntity> _dbSet;

    public Repository(DbContext context)
    {
        _context = context;
        _dbSet = context.Set<TEntity>();
    }
    public TEntity Add(TEntity entity)
    {
        entity.CreateDate = DateTime.Now;
        _dbSet.Add(entity);
        Save();
        return entity;
    }
    public void Save()
    {
        _context.SaveChanges();
    }
}

I tried to make it asynchronous, but I couldn't decide how both the adding and saving method will be asynchronous at the same time.我试图让它异步,但我无法决定添加和保存方法如何同时异步。 My experiment is here and it doesn't look right because it contains two await.我的实验在这里,它看起来不正确,因为它包含两个等待。

public abstract class Repository<TEntity> : IRepository<TEntity> where TEntity : Entity
{
    private readonly DbContext _context;
    private readonly DbSet<TEntity> _dbSet;

    public Repository(DbContext context)
    {
        _context = context;
        _dbSet = context.Set<TEntity>();
    }

    public async Task<TEntity> AddAsync(TEntity entity)
    {
        entity.CreateDate = DateTime.Now;
        await _dbSet.AddAsync(entity);
        await SaveAsync();
        return entity;
    }

    public async Task SaveAsync()
    {
        await _context.SaveChangesAsync();
    }
}

Actually, your base repository is not wrong, but unfortunately, most of us are using the Asynchronous programming and Async, await manner without a deep understanding.其实你的基础仓库没有错,可惜我们大部分人都是使用Asynchronous programmingAsync, await方式没有深入了解。 I recommend visiting this link Asynchronous Programming , anyway无论如何,我建议访问此链接异步编程

1. The await operator is applied to a task in an asynchronous method, and a hanging start point is inserted in the execution of the method until the waiting task is completed. 1 、await算子在异步方法中应用于任务,在方法执行中插入一个悬空起点,直到等待任务完成。 The task indicates the work in progress.任务指示正在进行的工作。

2 、await only can be used in asynchronous methods modified by the async keyword. 2 、await只能用在async关键字修饰的异步方法中。 This type of method, defined with the async modifier and usually containing one or more await expressions, is called an asynchronous method.这种类型的方法,用 async 修饰符定义,通常包含一个或多个 await 表达式,称为异步方法。

3 , the only purpose of await is to suspend this method when calling the asynchronous method XXAsync(). 3 、await的唯一目的就是在调用异步方法XXAsync()的时候挂起这个方法。 It considers this method to be a time-consuming method, the main thread, or the thread that calls this method.它认为这个方法是一个耗时的方法,主线程,或者调用这个方法的线程。 Do not wait in this way.不要以这种方式等待。 and mark it at the same time.并同时标记。 When the currently executing thread finishes running, it will resume running from here, so the code or method below the await tag's asynchronous method will not run.当前执行的线程运行结束后,会从这里恢复运行,所以await标签的异步方法下面的代码或方法不会运行。 You must wait for this method.您必须等待此方法。 carry out!执行!

4 , plus or not await, and whether the method is asynchronous or synchronous does not matter Write an example below 4 、加不加await,方法是异步还是同步无所谓下面写个例子

 private static async Task XAsync()
  {            
     await  XXAsync();
     OtherMothod();   
  }

5 . 5 . When running to await XXAsync(), the call to method XAsync() will no longer run and return directly, just like the return statement in our program code.当运行到 await XXAsync() 时,对方法 XAsync() 的调用将不再运行并直接返回,就像我们程序代码中的 return 语句一样。 The advantage of this is that the calling thread will not wait for this time-consuming thread.这样做的好处是调用线程不会等待这个耗时的线程。 Directly let the calling thread run down,直接让调用线程跑下来,

6 . 6 . If the calling thread always has the await chain up, just like the return in the method set method, it will return upwards layer by layer, returning to the main thread, and each "child thread" Wait for time-consuming I/O processing, such as manipulating databases and network flows如果调用线程总是有await链向上,就像方法set方法中的return一样,会一层层向上返回,返回到主线程,每个“子线程”都等待耗时的I/O处理,例如操作数据库和网络流

7 . 7 . We want to execute our program in multi-threaded or multi-tasking, let the time-consuming task get executed, and at the same time give the caller a quick response, no matter whether he has completed the task.我们希望以多线程或多任务的方式执行我们的程序,让耗时的任务得到执行,同时让调用者快速响应,无论他是否完成了任务。 It is the real purpose.这是真正的目的。

private static async TaskXAsync()
  {
           
    await  XXAsync();

    await  XXXAsync(); 
  }

XXXAsync() must wait for the XXAsync() method to execute, This will not affect the caller's response speed, but it will affect the execution efficiency of our code. XXXAsync() 必须等待 XXAsync() 方法执行,这不会影响调用者的响应速度,但会影响我们代码的执行效率。 which is slightly different from the two synchronization methods.这与两种同步方法略有不同。

private static async TaskXAsync()
  {
           
    XX();

    XXX(); 
  }

Like the above examples XX () and XXX () two synchronization methods, not only in order but the caller can not get the call right, that is, can not respond in time, must wait until both methods are finished.像上面例子中的XX()和XXX()两个同步方法,不仅顺序而且调用者不能正确调用,也就是不能及时响应,必须等到两个方法都执行完。 I hope that would be helpful我希望这会有所帮助

public interface IRepository<TEntity> where TEntity : class
{
    IQueryable<TEntity> GetAll();
    IQueryable<TEntity> GetByWhere(Expression<Func<TEntity, bool>> predicate);
   
    Task CreateAsync(TEntity entity);

    Task UpdateAsync(TEntity entity);

    Task DeleteAsync(TEntity entity);
}

 
       public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
        {
            private readonly DbContext dbContext;
    
            public Repository(DbContext dbContext)
            {
                this.dbContext = dbContext;
            }
    
            public async Task CreateAsync(TEntity entity)
            {
                await dbContext.Set<TEntity>().AddAsync(entity);
                await dbContext.SaveChangesAsync();
            }
    
            public async Task DeleteAsync(TEntity entity)
            {
                dbContext.Set<TEntity>().Remove(entity);
                await dbContext.SaveChangesAsync();
            }
    

    
            public IQueryable<TEntity> GetAll()
            {
                return dbContext.Set<TEntity>().AsNoTracking();
            }
    
            public IQueryable<TEntity> GetByWhere(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate)
            {
                return dbContext.Set<TEntity>().Where(predicate).AsNoTracking();
            }
    
            public async Task UpdateAsync(TEntity entity)
            {
                dbContext.Update(entity);
                await dbContext.SaveChangesAsync();
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM