如何使用 EF 存储库模式从 Azure Web 作业更新数据库?
How to use EF Repository Pattern to update Database from Azure Web Job?
使用 Entity Framework 从 Azure Web 作业 更新 SQL Azure 的正确方法是什么?
我只找到了 post SQL Azure using Azure Web Job
但是上面的解决方案使用SQL客户端没有通过Entity Framework!!!
可以在 Azure Web Job
下正确地调用代码 运行
public void DoSomething([TimerTrigger("*/5 * * * * *")] TimerInfo timer, TextWriter log)
{
try
{
var tempdetails = _sampleRepository.SearchFor(x=> DateTime.UtcNow > x.DateTo);
foreach (var detail in tempdetails)
{
if (detail.ID == 2)
{
detail.ID = 5;
}
_sampleRepository.Update(detail);
}
_unitOfWork.Commit();
}
catch (Exception ex)
{
log.WriteLine(ex.Message);
}
}
Ninject绑定
public class NinjectBindings : NinjectModule
{
public override void Load()
{
//Register Context
Kernel.Bind<MyDbContext>().ToSelf();
Kernel.Bind<IUnitOfWork<MyDbContext>>().To<UnitOfWork<MyDbContext>>();
//Register Repository
Kernel.Bind(x => x
.FromAssemblyContaining<MyDbContext>()
.SelectAllClasses()
.InheritedFrom(typeof(IRepository<>))
.BindDefaultInterface());
}
}
Program.CS
static void Main()
{
using (IKernel kernel = new StandardKernel(new NinjectBindings()))
{
var config = new JobHostConfiguration()
{
JobActivator = new NinjectJobActivator(kernel)
};
if (config.IsDevelopment)
{
config.UseDevelopmentSettings();
}
config.UseTimers();
var host = new JobHost(config);
host.RunAndBlock();
}
}
App.Config
<connectionStrings>
<add name="AzureWebJobsDashboard" connectionString="" />
<add name="AzureWebJobsStorage" connectionString="" />
<add name="EFContext" connectionString="Server=xxxx,1433;Initial Catalog=xxxxxx;....;User
ID=xxxxxxx;Password=xxxxxxxx;...;Encrypt=True;TrustServerCertificate=False;Connection
Timeout=30;App=EntityFramework" providerName="System.Data.SqlClient" /> </connectionStrings>
"Azure Portal Setting to Run Web Job"
As discussed with [ MS Support ] , after we added the
AzureWebJobsStorage and AzureWebJobDashboard connection strings as the Application settings blade in Azure Portal the web-job started to work
without the exception.
如何找出波纹管问题的根本原因
[工作代码 - 更新数据库]
var tempdetails = _myRepository.SearchFor(condifiotn);
if(tempdetails != null)
{
foreach (var detail in tempdetails)
{
_unitOfWork.GetContext.Entry(detail).State = EntityState.Detached;
//Do Some Modification
detail.Name = "Test";
_unitOfWork.GetContext.Entry(detail).State = EntityState.Modified;
}
//Save Changes
_unitOfWork.Commit();
}
[代码不工作 - 无法更新数据库]
var tempdetails = _myRepository.SearchFor(condifiotn);
if(tempdetails != null)
{
foreach (var detail in tempdetails)
{
//Do Some Modification
detail.Name = "Test";
_myRepository.Update(detail);
}
//Save Changes
_unitOfWork.Commit();
}
更新方法
public void Update(E entity)
{
//_dbSet.Attach(entity);
UnitOfWork.GetContext.Entry(entity).State = System.Data.Entity.EntityState.Modified;
}
根据您的描述,我按照此 tutorial 在我的 Azure Web 作业中实现了我的存储库和工作单元模式。您可以按照下面的代码片段检查您的代码。
NinjectBindings:
public class NinjectBindings : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<DbContext>().ToMethod(ctx=> {
return new BruceDbContext();
});
Bind<IUnitOfWork>().To<UnitOfWork>();
}
}
BruceDbContext:
public class BruceDbContext : DbContext
{
public BruceDbContext()
: base("name=brucedbcontext")
{
}
public BruceDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
{
}
//...
}
工作单位:
public class UnitOfWork : IUnitOfWork
{
private readonly DbContext _dbContext;
public UnitOfWork(DbContext dbContext)
{
_dbContext = dbContext;
}
public IRepository<Author> AuthorRepository =>
new GenericRepository<Author>(_dbContext);
public void SaveChanges()
{
_dbContext.SaveChanges();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
Functions.cs
public class Functions
{
private static IUnitOfWork _iUnitOfWork;
public Functions(IUnitOfWork iUnitOfWork)
{
_iUnitOfWork = iUnitOfWork;
}
public void DoSomething([TimerTrigger("*/30 * * * * *")] TimerInfo timer, TextWriter log)
{
_iUnitOfWork.AuthorRepository.Add(new Author()
{
Name = Guid.NewGuid().ToString()
});
_iUnitOfWork.Commit();
var allRecords=_iUnitOfWork.AuthorRepository.GetAll().ToList();
Console.WriteLine(JsonConvert.SerializeObject(allRecords));
}
}
注意:因为你使用的是TimerTrigger
,你需要在构造JobHost
之前调用config.UseTimers();
。此外,您可以在本地调试您的网络作业以查找详细错误。或者您可以更新您的问题并提供更详细的错误信息(例如 ex.StackTrace),以便我们缩小此问题的范围。
Ninject 在 Singleton Scope
中的绑定作为例外完成工作。我知道这不是最好的解决方案。等待最佳答案。如果我如何在 Call Scope.
中配置 Ninject
//注册上下文
Kernel.Bind<MyDbContext>().ToSelf().InSingletonScope();
Kernel.Bind<IUnitOfWork<MyDbContext>>().To<UnitOfWork<MyDbContext>>().InSingletonScope();
[ 使用 InSingletonScope
波纹管代码按预期工作 ]
var tempdetails = _myRepository.SearchFor(condifiotn);
if(tempdetails != null)
{
foreach (var detail in tempdetails)
{
//Do Some Modification
detail.Name = "Test";
_myRepository.Update(detail);
}
//Save Changes
_unitOfWork.Commit();
}
使用 Entity Framework 从 Azure Web 作业 更新 SQL Azure 的正确方法是什么?
我只找到了 post SQL Azure using Azure Web Job
但是上面的解决方案使用SQL客户端没有通过Entity Framework!!!
可以在 Azure Web Job
下正确地调用代码 运行public void DoSomething([TimerTrigger("*/5 * * * * *")] TimerInfo timer, TextWriter log)
{
try
{
var tempdetails = _sampleRepository.SearchFor(x=> DateTime.UtcNow > x.DateTo);
foreach (var detail in tempdetails)
{
if (detail.ID == 2)
{
detail.ID = 5;
}
_sampleRepository.Update(detail);
}
_unitOfWork.Commit();
}
catch (Exception ex)
{
log.WriteLine(ex.Message);
}
}
Ninject绑定
public class NinjectBindings : NinjectModule
{
public override void Load()
{
//Register Context
Kernel.Bind<MyDbContext>().ToSelf();
Kernel.Bind<IUnitOfWork<MyDbContext>>().To<UnitOfWork<MyDbContext>>();
//Register Repository
Kernel.Bind(x => x
.FromAssemblyContaining<MyDbContext>()
.SelectAllClasses()
.InheritedFrom(typeof(IRepository<>))
.BindDefaultInterface());
}
}
Program.CS
static void Main()
{
using (IKernel kernel = new StandardKernel(new NinjectBindings()))
{
var config = new JobHostConfiguration()
{
JobActivator = new NinjectJobActivator(kernel)
};
if (config.IsDevelopment)
{
config.UseDevelopmentSettings();
}
config.UseTimers();
var host = new JobHost(config);
host.RunAndBlock();
}
}
App.Config
<connectionStrings>
<add name="AzureWebJobsDashboard" connectionString="" />
<add name="AzureWebJobsStorage" connectionString="" />
<add name="EFContext" connectionString="Server=xxxx,1433;Initial Catalog=xxxxxx;....;User
ID=xxxxxxx;Password=xxxxxxxx;...;Encrypt=True;TrustServerCertificate=False;Connection
Timeout=30;App=EntityFramework" providerName="System.Data.SqlClient" /> </connectionStrings>
"Azure Portal Setting to Run Web Job"
As discussed with [ MS Support ] , after we added the AzureWebJobsStorage and AzureWebJobDashboard connection strings as the Application settings blade in Azure Portal the web-job started to work without the exception.
如何找出波纹管问题的根本原因
[工作代码 - 更新数据库]
var tempdetails = _myRepository.SearchFor(condifiotn);
if(tempdetails != null)
{
foreach (var detail in tempdetails)
{
_unitOfWork.GetContext.Entry(detail).State = EntityState.Detached;
//Do Some Modification
detail.Name = "Test";
_unitOfWork.GetContext.Entry(detail).State = EntityState.Modified;
}
//Save Changes
_unitOfWork.Commit();
}
[代码不工作 - 无法更新数据库]
var tempdetails = _myRepository.SearchFor(condifiotn);
if(tempdetails != null)
{
foreach (var detail in tempdetails)
{
//Do Some Modification
detail.Name = "Test";
_myRepository.Update(detail);
}
//Save Changes
_unitOfWork.Commit();
}
更新方法
public void Update(E entity)
{
//_dbSet.Attach(entity);
UnitOfWork.GetContext.Entry(entity).State = System.Data.Entity.EntityState.Modified;
}
根据您的描述,我按照此 tutorial 在我的 Azure Web 作业中实现了我的存储库和工作单元模式。您可以按照下面的代码片段检查您的代码。
NinjectBindings:
public class NinjectBindings : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<DbContext>().ToMethod(ctx=> {
return new BruceDbContext();
});
Bind<IUnitOfWork>().To<UnitOfWork>();
}
}
BruceDbContext:
public class BruceDbContext : DbContext
{
public BruceDbContext()
: base("name=brucedbcontext")
{
}
public BruceDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
{
}
//...
}
工作单位:
public class UnitOfWork : IUnitOfWork
{
private readonly DbContext _dbContext;
public UnitOfWork(DbContext dbContext)
{
_dbContext = dbContext;
}
public IRepository<Author> AuthorRepository =>
new GenericRepository<Author>(_dbContext);
public void SaveChanges()
{
_dbContext.SaveChanges();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
Functions.cs
public class Functions
{
private static IUnitOfWork _iUnitOfWork;
public Functions(IUnitOfWork iUnitOfWork)
{
_iUnitOfWork = iUnitOfWork;
}
public void DoSomething([TimerTrigger("*/30 * * * * *")] TimerInfo timer, TextWriter log)
{
_iUnitOfWork.AuthorRepository.Add(new Author()
{
Name = Guid.NewGuid().ToString()
});
_iUnitOfWork.Commit();
var allRecords=_iUnitOfWork.AuthorRepository.GetAll().ToList();
Console.WriteLine(JsonConvert.SerializeObject(allRecords));
}
}
注意:因为你使用的是TimerTrigger
,你需要在构造JobHost
之前调用config.UseTimers();
。此外,您可以在本地调试您的网络作业以查找详细错误。或者您可以更新您的问题并提供更详细的错误信息(例如 ex.StackTrace),以便我们缩小此问题的范围。
Ninject 在 Singleton Scope
中的绑定作为例外完成工作。我知道这不是最好的解决方案。等待最佳答案。如果我如何在 Call Scope.
//注册上下文
Kernel.Bind<MyDbContext>().ToSelf().InSingletonScope();
Kernel.Bind<IUnitOfWork<MyDbContext>>().To<UnitOfWork<MyDbContext>>().InSingletonScope();
[ 使用 InSingletonScope
波纹管代码按预期工作 ]
var tempdetails = _myRepository.SearchFor(condifiotn);
if(tempdetails != null)
{
foreach (var detail in tempdetails)
{
//Do Some Modification
detail.Name = "Test";
_myRepository.Update(detail);
}
//Save Changes
_unitOfWork.Commit();
}