2017-08-29 2 views
2

Un WebJob Azure s'exécute en continu et effectue des opérations CRUD dans ma base de données. J'utilise Entity Framework et UnitOfWork et dans mon WebJob j'utilise Autofac pour injecter mes couches de dépendances, de services et de référentiels. J'ai quelques problèmes avec les données périmées lors de l'exécution de mon WebJob.Nouveau DBContext en continu Azure WebJob en cours d'exécution

Exemple: Je mets à jour un enregistrement sur mon site Web et mon WebJob est alors lancé mais mon WebJob ne peut pas voir ce changement dans la base de données. Il voit l'enregistrement avant le changement.

Pour résoudre ce problème, j'ai essayé d'injecter mon contexte personnalisé comme celui-ci:

builder.RegisterType<PCContext>().As<IPCContext>().InstancePerDependency(); 

Après avoir fait que je peux voir les nouveaux changements dans la base de données. Mais maintenant j'ai d'autres problèmes. Lorsque j'insère un nouvel enregistrement puis le lit, je ne peux pas voir ce nouvel enregistrement depuis mon WebJob. Cela a bien fonctionné avant d'injecter mon contexte (comme indiqué dans le code ci-dessus).

Si je crée un nouveau contexte dans ma fonction WebJob je peux lire les mises à jour de la base de données, mais je veux utiliser ma couche de service à la place comme ceci:

_services.UserExport.ExportUsers(); 

Je ne peux pas comprendre ce que je fais mal ici. Ce que je veux c'est que chaque fois que ma fonction WebJob est lancée, je veux créer un nouveau contexte. Je suis sûr d'avoir les dernières mises à jour de la base de données et je veux pouvoir l'insérer dans ma base de données. mon WebJob en utilisant ma couche de service.

Quelqu'un peut-il me diriger dans la bonne direction?

Notez que mon WebJob est continu, donc son code d'enregistrement Autofac est uniquement exécuté une fois lorsque le WebJob est démarré, pas à chaque fois qu'une fonction dans le WebJob est exécutée.

S'il vous plaît laissez-moi savoir si plus de description ou de code est nécessaire.

Merci.

+0

Wow, je reçois le problème exact et observai quelques heures en arrière. J'aimerais aussi connaître la solution. –

+0

Appelez-vous 'SaveShanges' sur votre DbContext? – Steven

+0

Oui appelant 'SaveChanges' mais ne l'enregistrant pas dans la base de données. –

Répondre

0

Selon votre description, j'ai testé le scénario similaire de mon côté et j'ai trouvé que je pouvais lire et mettre à jour à partir de ma base de données. Je définissais mon générique Repository et UnitOfWork comme suit, vous pouvez les consulter:

Repository:

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 
} 

Pour ma WebJob je définissais les Fonctions .cs et initialisé le JobActivator comme suit:

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); 
+0

L'intention de cette réponse n'est pas claire ("* J'ai vérifié ce problème de mon côté *"). Êtes-vous en train de suggérer que ce code fonctionne pour vous et le PO devrait l'utiliser, ou avez-vous le même problème avec le code que vous avez inclus? – FluffyKitten

+1

Puisque op n'a pas fourni le code détaillé, j'ai écrit le code basé sur le scénario d'op pour vérifier ce problème. Le code ci-dessus pourrait fonctionner de mon côté, j'ai fourni le code pour op pour affiner ce problème. –

+0

Merci de mettre à jour votre réponse pour clarifier. – FluffyKitten