Created
February 8, 2018 03:32
-
-
Save NickPl/db294a19a382c2ad5c6b3cae4674a9bb to your computer and use it in GitHub Desktop.
Blog XrmMtl - Essential Plugin Class for Early Bound
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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