3 votes

Comment obtenir toutes les valeurs d'entités sauvegardées dans le DbContext, soit via les événements, soit en surchargeant SaveChangesAsync().

Besoin d'une solution centralisée pour obtenir les résultats Entity comme persisté dans la base de données, potentiellement à l'intérieur de la base de données de l'utilisateur. SaveChangesAsync() y SaveChanges() méthodes de mon DbContext ou via un écouteur d'événements.

La valeur de l'entité résultante doit contenir toutes les nouvelles .ValueGeneratedOnAdd[Updated/etc]() les propriétés, c'est-à-dire RowVersion , Updated etc.

Le but est de communiquer l'avant et l'après de la Entity pour la communication entre concurrents.

C'est ce que j'ai jusqu'à présent : Cette première méthode entraîne une attaque supplémentaire et inutile de la base de données.

public override async Task<int> SaveChangesAsync(
        CancellationToken cancellationToken = new CancellationToken() )
{
    var before = ChangeTracker.Entries().AsEnumerable().First();

    var res = await base.SaveChangesAsync(cancellationToken);

    /* ********************************************************           
       I can do the following, but this results in an extra 
       DbQuery. I know that if this were a  consumer 
       method with entity, after I called SaveChangesAsync() it 
       would have the new resulting values.  Just not sure how 
       to access here inside SaveChangesAsync()?
       ********************************************************** */
    await ChangeTracker.Entries().AsEnumerable().First().ReloadAsync(); 
    /* ********************************************************
       ^ Additionally, ReloadAsync has a "Note, however, that an 
       Added entity may not yet have had its permanent key value 
       created. 
       ********************************************************** */
    var after = ChangeTracker.Entries().AsEnumerable().First();

    return res;
}

En outre, j'ai souscrit au nouveau bulletin d'information de la événements de changement d'état Tracked y StateChagned qui sont mentionnés ou liés sur le numéro de github EntityFrameworkCore - Crochets de cycle de vie #626 : Pour Ex :

public class StateListener : IEntityStateListener
{
    public void StateChanging(InternalEntityEntry entry, EntityState newState)
    {
        Console.WriteLine(
            "  Changing {0} from {1} to {2}.",
            entry.Entity.GetType().Name, entry.EntityState, newState);
    }

    public void StateChanged(InternalEntityEntry entry, 
        EntityState oldState, bool fromQuery)
    {
        Console.WriteLine(
            "  Changed {0} to {1} from {2}.",
            entry.Entity.GetType().Name, entry.EntityState, oldState);
    }

    public void StateChanged(InternalEntityEntry entry, EntityState oldState,
        bool skipInitialFixup, bool fromQuery)
    {
        Console.WriteLine(
            "  Changed {0} from {1} to {2}.",
            entry.Entity.GetType().Name, oldState, entry.EntityState);
    }
}

Toutefois, la newState et le InternalEntityEntry en StateChanged tous posess les valeurs qui devraient être sauvegardées et non les nouvelles valeurs qui sont fixées par la Db, tel que RowVersion , Changed etc.

1voto

ttugates Points 1431

Réponse pour ceux qui ont une recherche similaire - En posant cette question, j'ai eu un malentendu fondamental. Je pensais qu'une entité persistée dans la base de données verrait toutes ses valeurs mises à jour le jour de l'événement. SaveChanges[Async]() . J'ai cru cela parce que c'est le comportement des clés primaires tel que décrit dans " Comment puis-je obtenir l'Id de l'entité insérée dans Entity framework ? "

Ce n'est pas le cas pour les propriétés qui sont .ValueGeneratedOnAdd[Updated/etc]() et ne sont pas des RowVersion ou des PrimaryKeys.

Avec cette compréhension, toute solution possible nécessiterait vraisemblablement une requête à la Db. J'ai envisagé d'ajouter une telle requête à la OnCommandExecuting et ensuite travailler avec le résultat dans OnCommandExecuted mais abandonné en raison de sa nature.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X