我正在连续运行Azure WebJob,它正在我的数据库中执行CRUD操作。我正在使用Entity Framework和UnitOfWork模式,在我的WebJob中,我使用Autofac来注入我的依赖项,服务和存储库层。运行我的WebJob时,我遇到了一些陈旧数据的问题。
实施例: 我在我的网站上更新了一条记录,然后我的WebJob被启动,但我的WebJob无法在数据库中看到此更改。它会在变更之前看到记录。
为了解决这个问题,我试着像这样注入自定义上下文:
builder.RegisterType<PCContext>().As<IPCContext>().InstancePerDependency();
执行此操作后,我可以看到数据库中的最新更改。但现在我有另外一个问题。当我插入新记录然后读取它时,从我的WebJob中我看不到这条新记录。在我注入上下文之前,这很好用(如上面的代码所示)。
如果我在WebJob函数中创建一个新的上下文,我可以从数据库中读取更新,但我想使用我的服务层,而不是这样:
_services.UserExport.ExportUsers();
我无法弄清楚我在这里做错了什么。基本上我想要的是每次我的WebJob功能启动时我想要创建一个新的上下文,所以我确信我有来自数据库的最新更新,我希望能够插入我的数据库并再次阅读我的WebJob使用我的服务层。
有人能指出我正确的方向吗?
请注意,我的WebJob是连续的,因此它的Autofac注册代码仅在WebJob启动时执行一次,而不是每次执行WebJob中的函数时都执行。
如果需要更多说明或代码,请与我们联系。
感谢。
答案 0 :(得分:0)
根据你的描述,我在我身边测试了类似的场景,我发现我可以从我的数据库中读取和更新。我将通用Repository
和UnitOfWork
定义如下,您可以参考它们:
<强>存储库:强>
public interface IRepository<T>
{
T GetById(object id);
IQueryable<T> GetAll();
void Edit(T entity);
void Insert(T entity);
void Delete(T entity);
}
public class Repository<T> : IRepository<T> where T : class
{
public DbContext context;
public DbSet<T> dbset;
public Repository(DbContext context)
{
this.context = context;
dbset = context.Set<T>();
}
public T GetById(object id)
{
return dbset.Find(id);
}
public IQueryable<T> GetAll()
{
return dbset;
}
public void Insert(T entity)
{
dbset.Add(entity);
}
public void Edit(T entity)
{
context.Entry(entity).State = EntityState.Modified;
}
public void Delete(T entity)
{
context.Entry(entity).State = EntityState.Deleted;
}
}
<强>的UnitOfWork:强>
public class UnitOfWork : IDisposable
{
private DbContext _context;
private Repository<TodoItem> toDoItemRepository;
public Repository<TodoItem> ToDoItemRepository
{
get
{
if (toDoItemRepository == null)
toDoItemRepository = new Repository<TodoItem>(_context);
return toDoItemRepository;
}
}
public UnitOfWork() : this(new BruceDbContext()) { }
public UnitOfWork(DbContext context)
{
_context = context;
}
public void Commit()
{
_context.SaveChanges();
}
#region Dispose
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
对于我的WebJob,我定义了 Functions.cs 并初始化了JobActivator
,如下所示:
<强> Functions.cs 强>
public class Functions
{
private UnitOfWork _unitOfWork;
public Functions(UnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public async Task CronJob([TimerTrigger("0/30 * * * * *")] TimerInfo timer, CancellationToken cancelToken)
{
//retrieve the latest record
var item = _unitOfWork.ToDoItemRepository.GetAll().OrderByDescending(i => i.CreateDate).FirstOrDefault();
Console.WriteLine($"[{item.CreateDate}] {item.Text}");
//insert a new record
_unitOfWork.ToDoItemRepository.Insert(new Entities.TodoItem()
{
Id = Guid.NewGuid().ToString(),
CreateDate = DateTime.Now,
Text = $"hello world -{DateTime.Now}"
});
_unitOfWork.Commit();
//retrieve the previous added record
item = _unitOfWork.ToDoItemRepository.GetAll().OrderByDescending(i => i.CreateDate).FirstOrDefault();
Console.WriteLine($"[{item.CreateDate}] {item.Text}");
}
}
<强> Program.cs的强>
var builder = new ContainerBuilder();
builder.Register<UnitOfWork>(c => new UnitOfWork(new BruceDbContext())).InstancePerDependency();
builder.RegisterType<Functions>();
var container = builder.Build();
var config = new JobHostConfiguration()
{
JobActivator = new AutoFacJobActivator(container)
};
var host = new JobHost(config);