如何使用EF存储库模式从Azure Web作业更新数据库?

问题描述 投票:0回答:2

从Azure Web Job使用Entity Framework更新SQL Azure的正确方法是什么?

我只能找到一个帖子SQL Azure using Azure Web Job

但是上面的解决方案使用SQL Client而不是通过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>

“用于运行Web作业的Azure门户设置”

正如[MS Support]所讨论的,在我们将AzureWebJobsStorage和AzureWebJobDashboard连接字符串添加为Azure门户中的应用程序设置刀片后,Web作业开始无异常地工作。

如何找出以下问题的根本原因

[工作代码 - 更新数据库]

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;
        }
c# entity-framework ninject repository-pattern azure-webjobs
2个回答
0
投票

根据你的描述,我按照这个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)
    {
    }

    //...
}

的UnitOfWork:

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,因此在构造config.UseTimers();之前需要调用JobHost。此外,您可以在本地调试您的webjob以查找详细错误。或者您可以更新您的问题并提供更详细的错误(例如ex.StackTrace),以便我们缩小此问题的范围。


0
投票

Singleton Scope的Ninject绑定做了例外。我知道这不是最好的解决方案。等待最好的ans。如果我在调用范围中配置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();
}
© www.soinside.com 2019 - 2024. All rights reserved.