CRM 2011 SDK交易(CRM 2011 SDK transaction)

2019-09-18 02:35发布

如何使用CRM 2011 SDK和XrmServiceContext创建交易?

在下面的例子中“new_brand”是一些自定义实体。 我想创建三个品牌。 三是有错OWNERID GUID。 当我打电话调用SaveChanges()方法,创建了两个品牌,我有例外。 如何回滚的第一两个品牌创建?

是否有可能不使用pluggins和工作流程?

using (var context = new XrmServiceContext(connection))
{
    SystemUser owner = context.SystemUserSet.FirstOrDefault(s => s.Id == new Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"));

    // create 3 brands
    new_brand b1 = new new_brand();
    b1.new_brandidentification = 200;
    b1.new_name = "BRAND 200";
    b1.OwnerId = owner.ToEntityReference();
    context.AddObject(b1);

    new_brand b2 = new new_brand();
    b2.new_brandidentification = 300;
    b2.new_name = "BRAND 300";
    b2.OwnerId = owner.ToEntityReference();
    context.AddObject(b2);

    new_brand b3 = new new_brand();
    b3.new_brandidentification = 400;
    b3.new_name = "BRAND 400";
    b3.OwnerId = new EntityReference(SystemUser.EntityLogicalName, new Guid("00000000-0000-0000-0000-000000000000"));
    context.AddObject(b3);

    context.SaveChanges();
}

Answer 1:

是否有可能不使用插件和工作流程?

不,我不认为它是。 每个context.AddObject()是原子的。 如果你不想使用插件那么我认为你可以做的是有一些那种删除创建的记录,如果你的条件不具备清理逻辑。



Answer 2:

CRM提供了交易的唯一的支持是一个插件中,我甚至不相信这将帮助你在这种情况下,因为一个品牌的每创作,将在自己的事务。

我能想到的来实现这种逻辑的最简单的方法是增加一个新的领域new_Brand叫new_TransactionGroupId,并用它来删除像这样创建的任何记录:

using (var context = new XrmServiceContext(connection))
{
    SystemUser owner = context.SystemUserSet.FirstOrDefault(s => s.Id == new Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"));
    var transactionGroupId = Guid.NewGuid();

    // create 3 brands
    new_brand b1 = new new_brand();
    b1.new_brandidentification = 200;
    b1.new_name = "BRAND 200";
    b1.OwnerId = owner.ToEntityReference();
    b1.new_TransactionGroupId = transactionGroupId ;
    context.AddObject(b1);

    new_brand b2 = new new_brand();
    b2.new_brandidentification = 300;
    b2.new_name = "BRAND 300";
    b2.OwnerId = owner.ToEntityReference();
    b2.new_TransactionGroupId = transactionGroupId ;
    context.AddObject(b2);

    new_brand b3 = new new_brand();
    b3.new_brandidentification = 400;
    b3.new_name = "BRAND 400";
    b3.OwnerId = new EntityReference(SystemUser.EntityLogicalName, new Guid("00000000-0000-0000-0000-000000000000"));
    b3.new_TransactionGroupId = transactionGroupId;
    context.AddObject(b3);

    try{
        context.SaveChanges();
    } catch (Exception ex){
        // Since one brand failed, cleanup all brands
        foreach(brand in context.new_brand.where(b => b.new_TransactionGroupId == transactionGroupId)){
            context.Delete(brand);
        }
    }
}


Answer 3:

其实这是可以不使用插件。

您可以使用CRM的关系链接强制交易行为:

EntityA primaryEntity = new EntityA() { //initialise me... };
EntityB secondaryEntity = new EntityB() { //initialise me... };

context.AddObject(primaryEntity);
context.AddObject(secondaryEntity);

// This is the key part: explicitly link the two entities
context.AddLink(primaryEntity, 
    new Relationship("relationship_name_here"), secondaryEntity);

// commit changes to CRM
context.SaveChanges();

有几个缺点,这种方式:

  • 显然,一个关系必须存在于CRM的两个实体之间。 如果没有关系的存在,你将不得不与一个插件。
  • 我个人觉得,如果你需要保存对象的大型层次结构都在一气呵成的代码会变得混乱。

另一种方法可能会考虑实施使用插件的命令模式。

这个想法是,你在客户端上创建CRM的对象,它们序列化,并通过自定义实体它们传递到CRM。 预创建的插件,然后建立这个实体去序列化和创建插件事务范围内的对象。

一个优秀的博客帖子描述两种策略可以在这里找到: http://crm.davidyack.com/journal/2012/6/26/crm-client-extension-data-access-strategies.html



文章来源: CRM 2011 SDK transaction