我有一个需要创建一堆实体的插件,并使用;
service.Create(Entity);
在插件结束时(更新前的操作,同步)我有时需要取消保存操作。我知道如何抛出异常的唯一方法,但如果我这样做,我的service.Create(实体)不会被执行。
如何强制服务执行插件内的操作,然后通过抛出异常来取消保存?
编辑:代码是;
var id = service.Create(newEntity);
throw new Exception("Cancelled Save but created the new entity");
如果我抛出异常,则不会创建实体。如果我不抛出异常,则实体会创建。我需要它来创建并抛出异常,以便取消保存操作。
感谢您的任何指示。
答案 0 :(得分:2)
如果IPluginExecutionContext.IsInTransaction == true
那么当抛出异常时,任何已写入数据库的内容都将被回滚。您可以尝试在预验证阶段注册,有时也可以在交易之外注册,但并非总是如此。
请注意,无法保证它永远不在交易之外。 SDK文档非常清楚 - 所以在任何时候都可能发生更新,将其置于事务中。
https://msdn.microsoft.com/en-us/library/gg327941.aspx#bkmk_DatabaseTransactions:
插件可能会也可能不会在数据库事务中执行 Microsoft Dynamics CRM平台。插件是否是其中的一部分 事务取决于消息请求的处理方式 管道。您可以检查插件是否在事务中执行 通过读取继承的IsInTransaction属性 传递给插件的IPluginExecutionContext。如果插件是 在数据库事务中执行并允许异常 传回平台,整个交易将被滚动 背部。第20和第40阶段保证是数据库的一部分 交易,而第10阶段可能是交易的一部分。
在数据库事务期间执行的任何已注册插件 并且将异常传递回平台会取消核心 操作。这导致核心操作的回滚。在 此外,任何事件前或事件后注册的插件都有 尚未执行以及由同一事件触发的任何工作流程 注册的插件将不会执行。
答案 1 :(得分:2)
Nicknow的回答是正确的,但仍有几种方法可以完成你想做的事。
在插件中,请勿使用插件上下文中的OrganizationService。创建自己的新OrganizationService就像创建控制台应用程序一样。此新OrganizationService不受原组织服务的事务范围的限制。
创建一个完成工作的Web服务。从您的插件中,调用此Web服务。 Web服务不受原组织服务的事务范围的限制。
使用ExecuteMultiple。我从来没有试过这个,但是有人声称它有效:http://crmtidbits.blogspot.com/2014/02/bypass-plug-in-transaction-to-log.html
希望有所帮助!