2010-01-11 9 views
0

Nous avons une application Silverlight qui utilise les services de données WCF. Nous voulons ajouter une fonctionnalité de journalisation: lorsqu'une nouvelle ligne est générée, la clé primaire de cette nouvelle ligne est également enregistrée dans la table de journalisation. La génération de ligne et la journalisation doivent se produire dans la même transaction. Les clés primaires sont générées via la base de données (en utilisant le mot clé IDENTITY).Services de données ADO.NET sur Silverlight: utilisation de la clé générée dans la même transaction

Ceci peut être mieux illustré par un exemple. Ici, je crée une nouvelle ligne Customer et, dans la même transaction, j'écris la clé primaire du client dans une ligne AuditLog. Cet exemple utilise un client lourd et Entity Framework:

using (var ts = new TransactionScope()) 
    { 
     AuditTestEntities entities = new AuditTestEntities(); 
     Customer c = new Customer(); 
     c.CustomerName = "Acme Pty Ltd"; 
     entities.AddToCustomer(c); 
     Debug.Assert(c.CustomerID == 0); 
     entities.SaveChanges(); 
     // The EntityFramework automatically updated the customer object 
     // with the newly generated key 
     Debug.Assert(c.CustomerID != 0); 
     AuditLog al = new AuditLog(); 
     al.EntryDateTime = DateTime.Now; 
     al.Description = string.Format("Created customer with customer id {0}", c.CustomerID); 
     entities.AddToAuditLog(al); 
     entities.SaveChanges(); 
     ts.Complete(); 
    } 

C'est un problème trivial lors de l'élaboration d'un client lourd en utilisant Entity Framework.

Cependant, l'utilisation des services de données Silverlight et de ADO.NET:

  • SaveChanges ne peut être invoqué de manière asynchrone
  • Je ne suis pas sûr TransactionScope est disponible
  • Je ne suis pas sûr si les clés générées peut être reflété dans le client Éditer: Selon Alex James ils sont en effet reflétés dans le client

Alors, cela sera-t-il encore possible?

Répondre

4

Réponse courte: Non, ce n'est pas même possible

Ok ... donc:

  1. Les clés générées sont reflétées dans le client.
  2. Vous pouvez traiter une opération SaveChanges à l'aide de DataServiceContext. SaveChanges (SaveChangesOption.Batch)

Mais, malheureusement, vous ne pouvez rien faire pour attacher une demande à la réponse d'une autre, et les envelopper à la fois dans une seule transaction.

Mais ...

Si vous changez le modèle en faisant une méthode CustomerAuditLog qui dérive de AuditLog:

// Create and insert customer ... 
// Create audit log and relate to un-insert customer 
CustomerAuditLog al = new CustomerAuditLog(); 
al.EntryDateTime = DateTime.Now; 
al.Description = string.Format("Created customer with {Customer.ID}"); 
// assuming your entities implement INotifyPropertyChanging and you are using 
// the Data Services Update to .NET 3.5 SP1 to use DataServiceCollection 
// to notify the DataServiceContext that a relationship has been formed. 
// 
// If not you will manually need to tell Astoria about the relationship too. 
al.Customer = c; 
entities.AddToAuditLog(al); 
entities.SaveChanges(); 

Et avoir une sorte de logique profonde dans votre DataSource sous-jacente ou peut-être même la base de données pour remplacer {Customer.ID} avec la valeur appropriée.

Vous pouvez le faire fonctionner, car si deux insertions se produisent dans la même transaction et qu'une (CustomerAuditLog) dépend d'une autre (Customer), elles doivent être classées de manière appropriée par la source de données sous-jacente.

Mais comme vous pouvez voir cette approche est un peu hacky, vous ne voulez pas un type pour chaque message d'audit possible que vous faites! Et ... ça ne marchera peut-être même pas.

Hope this helps

Alex

données Team Services, Microsoft

Questions connexes