0

我们有一个使用 WCF 数据服务的 Silverlight 应用程序。我们要添加日志功能:当生成新行时,该新行的主键也记录在日志表中。行生成和日志记录应该发生在同一个事务中。主键是通过数据库生成的(使用 IDENTITY 关键字)。

最好用一个例子来说明这一点。在这里,我创建了一个新的Customer行,并在同一个事务中将 Customer 的主键写入AuditLog行。此示例使用胖客户端和实体框架:

    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();
    }

使用 Entity Framework 开发胖客户端时,这是一个小问题。

但是,使用 Silverlight 和 ADO.NET 数据服务:

  • SaveChanges 只能异步调用
  • 我不确定 TransactionScope 是否可用
  • 我不确定生成的密钥是否可以反映在客户端编辑:根据Alex James的说法,它们确实反映在客户端

那么,这甚至可能吗?

4

1 回答 1

4

简短的回答:不,这甚至是不可能的

可以,然后呢:

  1. 生成的密钥反映在客户端中。
  2. 您可以使用 DataServiceContext 执行一项 SaveChanges 操作。SaveChanges ( SaveChangesOption.Batch )

但不幸的是,您无法将一个请求与另一个请求的响应联系起来,并将它们包装在一个事务中。

然而...

如果您通过创建派生自 AuditLog 的 CustomerAuditLog 方法来更改模型:

// 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();

并且在您的底层数据源甚至数据库中拥有某种逻辑,以用适当的值替换 {Customer.ID}。

您也许可以让它工作,因为如果两个插入发生在同一个事务中并且一个 (CustomerAuditLog) 依赖于另一个 (Customer),则它们应该由基础数据源适当地排序。

但是正如您所看到的,这种方法有点老套,您不希望每个可能的审计消息都有一个类型吗?而且......它甚至可能不起作用。

希望这可以帮助

亚历克斯

微软数据服务团队

于 2010-01-12T23:48:21.410 回答