Skip to content

Instantly share code, notes, and snippets.

@NickPl
Created February 8, 2018 03:32
Show Gist options
  • Save NickPl/db294a19a382c2ad5c6b3cae4674a9bb to your computer and use it in GitHub Desktop.
Save NickPl/db294a19a382c2ad5c6b3cae4674a9bb to your computer and use it in GitHub Desktop.
Blog XrmMtl - Essential Plugin Class for Early Bound
using <GeneratedEntities>;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Xrm.Plugins.Sandbox
{
/// <summary>
/// Creates a dual context to read and write. The goal is to decouple reading and writing because the
/// orignal context does not handle it well.
/// </summary>
public class DualXrmServiceContext : XrmServiceContext
{
protected XrmServiceContext Write
{
get;
private set;
}
public DualXrmServiceContext(IOrganizationService org)
: base(org)
{
Write = new XrmServiceContext(org);
}
public new void AddLink(Entity source, Relationship relationship, Entity target)
{
Write.AddLink(source, relationship, target);
}
public new void AddObject(Entity entity)
{
Write.AddObject(entity);
}
public new void AddRelatedObject(Entity source, Relationship relationship, Entity target)
{
Write.AddRelatedObject(source, relationship, target);
}
public new void Attach(Entity entity)
{
Write.Attach(entity);
}
public new void AttachLink(Entity source, Relationship relationship, Entity target)
{
Write.AttachLink(source, relationship, target);
}
public new void ClearChanges()
{
Write.ClearChanges();
}
public new void DeleteLink(Entity source, Relationship relationship, Entity target)
{
Write.DeleteLink(source, relationship, target);
}
public new void DeleteObject(Entity entity)
{
entity = QuickMergeWithContext(entity);
Write.DeleteObject(entity);
}
public new void DeleteObject(Entity entity, bool recursive)
{
Write.DeleteObject(entity, recursive);
}
public new bool Detach(Entity entity)
{
return Write.Detach(entity);
}
public new bool Detach(Entity entity, bool recursive)
{
return Write.Detach(entity, recursive);
}
public new bool DetachLink(Entity source, Relationship relationship, Entity target)
{
return Write.DetachLink(source, relationship, target);
}
public new void Dispose()
{
this.Dispose();
Write.Dispose();
}
public new OrganizationResponse Execute(OrganizationRequest request)
{
return Write.Execute(request);
}
public new IEnumerable<Entity> GetAttachedEntities()
{
return Write.GetAttachedEntities();
}
public new bool IsAttached(Entity entity)
{
// That way is better than the original
return Write.GetAttachedEntities().Where(x => x.Id == entity.Id).FirstOrDefault() != null;
//return Write.IsAttached(entity);
}
public new bool IsAttached(Entity source, Relationship relationship, Entity target)
{
return Write.IsAttached(source, relationship, target);
}
public new bool IsDeleted(Entity entity)
{
return Write.IsDeleted(entity);
}
public new bool IsDeleted(Entity source, Relationship relationship, Entity target)
{
return Write.IsDeleted(source, relationship, target);
}
public new SaveChangesResultCollection SaveChanges()
{
return this.Write.SaveChanges();
}
public new SaveChangesResultCollection SaveChanges(SaveChangesOptions options)
{
return this.Write.SaveChanges(options);
}
public new void UpdateObject(Entity entity)
{
entity = MergeWithContext(entity);
this.Write.UpdateObject(entity);
}
public new void UpdateObject(Entity entity, bool recursive)
{
entity = MergeWithContext(entity);
this.Write.UpdateObject(entity, recursive);
}
private Entity MergeWithContext(Entity e)
{
if (this.IsAttached(e))
{
var newEntity = this.Write.GetAttachedEntities().Where(x => x.Id == e.Id).FirstOrDefault();
if (newEntity.GetHashCode() == e.GetHashCode())
return newEntity;
foreach (var attrib in e.Attributes)
{
if (newEntity.Contains(attrib.Key))
newEntity[attrib.Key] = e[attrib.Key];
else
newEntity.Attributes.Add(attrib);
}
e = newEntity;
}
else
{
base.ClearChanges();
this.Write.Attach(e);
}
return e;
}
private Entity QuickMergeWithContext(Entity e)
{
if (this.IsAttached(e))
{
var newEntity = this.Write.GetAttachedEntities().Where(x => x.Id == e.Id).FirstOrDefault();
e = newEntity;
}
else
{
base.ClearChanges();
this.Write.Attach(e);
}
return e;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment