如何使用 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();
}