Skip to content

Instantly share code, notes, and snippets.

@temmyraharjo
Created July 3, 2021 11:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save temmyraharjo/afaabc1a56927d9c57e359f2d4188838 to your computer and use it in GitHub Desktop.
Save temmyraharjo/afaabc1a56927d9c57e359f2d4188838 to your computer and use it in GitHub Desktop.
Dynamics CRM Azure Redis Cache Demonstration for Power Maverick
using Microsoft.Xrm.Sdk;
using System;
namespace Demo.Entities
{
[System.Runtime.Serialization.DataContractAttribute]
[Microsoft.Xrm.Sdk.Client.EntityLogicalNameAttribute("account")]
public class Account : Entity
{
public const string EntityLogicalName = "account";
public Account() : base(EntityLogicalName)
{
}
[System.ComponentModel.DataAnnotations.Schema.Column("accountid")]
public override Guid Id
{
get { return base.Id; }
set
{
base.Id = value;
this["accountid"] = value;
}
}
public readonly string EMailAddress3 = null;
public readonly string EMailAddress2 = null;
public readonly string EMailAddress1 = null;
public readonly string Address1_City = null;
public readonly EntityReference SLAId = null;
public readonly DateTime? ModifiedOn = null;
public readonly Money Aging90 = null;
public readonly DateTime? OverriddenCreatedOn = null;
public readonly string WebSiteURL = null;
public readonly double? Address1_Longitude = null;
public readonly bool? DoNotPostalMail = null;
public readonly OptionSetValue Address1_AddressTypeCode = null;
public readonly EntityReference TransactionCurrencyId = null;
public readonly int? SharesOutstanding = null;
public readonly bool? DoNotSendMM = null;
public readonly EntityReference CreatedByExternalParty = null;
public readonly bool? CreditOnHold = null;
public readonly Money Aging30 = null;
public readonly bool? DoNotBulkPostalMail = null;
public readonly string YomiName = null;
public readonly OptionSetValue Address1_ShippingMethodCode = null;
public readonly OptionSetValue PaymentTermsCode = null;
public readonly EntityReference SLAInvokedId = null;
public readonly OptionSetValue AccountCategoryCode = null;
public readonly string Address2_StateOrProvince = null;
public readonly string Address2_Country = null;
public readonly string Address2_Line2 = null;
public readonly Money Aging60_Base = null;
public readonly string Address1_Line3 = null;
public readonly int? OnHoldTime = null;
public readonly OptionSetValue Address1_FreightTermsCode = null;
public readonly Money CreditLimit = null;
public readonly OptionSetValue AccountRatingCode = null;
public readonly int? Address1_UTCOffset = null;
public readonly OptionSetValue PreferredAppointmentTimeCode = null;
public readonly int? NumberOfEmployees = null;
public readonly OptionSetValue AccountClassificationCode = null;
public readonly Money Revenue = null;
public readonly OptionSetValue CustomerTypeCode = null;
public readonly decimal? ExchangeRate = null;
public readonly string Address2_County = null;
public readonly bool? IsPrivate = null;
public readonly EntityReference PrimaryContactId = null;
public readonly string Telephone3 = null;
public readonly EntityReference ParentAccountId = null;
public readonly string Address2_City = null;
public readonly OptionSetValue StatusCode = null;
public readonly double? Address2_Latitude = null;
public readonly DateTime? CreatedOn = null;
public readonly bool? DoNotBulkEMail = null;
public readonly bool? DoNotFax = null;
public readonly Money MarketCap = null;
public readonly string Address1_Composite = null;
public readonly OptionSetValue OwnershipCode = null;
public readonly EntityReference OwningBusinessUnit = null;
public readonly string Address2_PostalCode = null;
public readonly DateTime? LastUsedInCampaign = null;
public readonly Guid? ProcessId = null;
public readonly string Address2_Line3 = null;
public readonly string Description = null;
public readonly EntityReference ModifiedBy = null;
public readonly int? TimeZoneRuleVersionNumber = null;
public readonly string Address1_County = null;
public readonly OptionSetValue PreferredContactMethodCode = null;
public readonly EntityReference ModifiedOnBehalfBy = null;
public readonly string Address1_Line1 = null;
public readonly bool? DoNotEMail = null;
public readonly OptionSetValue TerritoryCode = null;
public readonly string Address2_PostOfficeBox = null;
public readonly string Address2_Telephone1 = null;
public readonly string Address2_Telephone2 = null;
public readonly string Address2_Telephone3 = null;
public readonly Guid? Address1_AddressId = null;
public readonly string TraversedPath = null;
public readonly string Address1_Telephone2 = null;
public readonly EntityReference OwningUser = null;
public readonly OptionSetValue IndustryCode = null;
public readonly string Address2_Name = null;
public readonly string PrimarySatoriId = null;
[System.ComponentModel.DataAnnotations.KeyAttribute]
public readonly string Name = null;
public readonly Money Aging60 = null;
public readonly string TimeSpentByMeOnEmailAndMeetings = null;
public readonly OptionSetValue BusinessTypeCode = null;
public readonly string PrimaryTwitterId = null;
public readonly byte[] EntityImage = null;
public readonly string Address2_Composite = null;
public readonly OptionSetValue ShippingMethodCode = null;
public readonly string Address1_Country = null;
public readonly EntityReference OwningTeam = null;
public readonly string Address1_StateOrProvince = null;
public readonly bool? MarketingOnly = null;
public readonly EntityReference CreatedOnBehalfBy = null;
public readonly string Address2_Line1 = null;
public readonly string Address1_Telephone1 = null;
public readonly string Address1_Telephone3 = null;
public readonly string Address1_PostOfficeBox = null;
public readonly bool? FollowEmail = null;
public readonly string Fax = null;
public readonly EntityReference MasterId = null;
public readonly string SIC = null;
public readonly EntityReference OwnerId = null;
public readonly int? Address2_UTCOffset = null;
public readonly Guid? StageId = null;
public readonly string AccountNumber = null;
public readonly Money CreditLimit_Base = null;
public readonly string Address2_Fax = null;
public readonly Money Revenue_Base = null;
public readonly bool? Merged = null;
public readonly double? Address2_Longitude = null;
public readonly EntityReference ModifiedByExternalParty = null;
public readonly string FtpSiteURL = null;
public readonly Money Aging90_Base = null;
public readonly bool? DoNotPhone = null;
public readonly string Address1_PrimaryContactName = null;
public readonly DateTime? LastOnHoldTime = null;
public readonly string Address1_Line2 = null;
public readonly EntityReference CreatedBy = null;
public readonly OptionSetValue Address2_AddressTypeCode = null;
public readonly string Address2_UPSZone = null;
public readonly Money MarketCap_Base = null;
public readonly string Address1_PostalCode = null;
public readonly string TickerSymbol = null;
public readonly OptionSetValue CustomerSizeCode = null;
public readonly int? UTCConversionTimeZoneCode = null;
public readonly bool? ParticipatesInWorkflow = null;
public readonly string StockExchange = null;
public readonly int? ImportSequenceNumber = null;
public readonly string Telephone2 = null;
public readonly int? VersionNumber = null;
public readonly EntityReference PreferredSystemUserId = null;
public readonly Guid? AccountId = null;
public readonly string Telephone1 = null;
public readonly Money Aging30_Base = null;
public readonly string Address1_Name = null;
public readonly string Address1_Fax = null;
public readonly double? Address1_Latitude = null;
public readonly OptionSetValue Address2_ShippingMethodCode = null;
public readonly OptionSetValue PreferredAppointmentDayCode = null;
public readonly OptionSetValue Address2_FreightTermsCode = null;
public readonly string Address1_UPSZone = null;
public readonly Guid? Address2_AddressId = null;
public readonly string Address2_PrimaryContactName = null;
[System.ComponentModel.DescriptionAttribute("{\"a\":0}")]
public readonly OptionSetValue StateCode = null;
public new static class Options
{
public enum Address1_AddressTypeCode
{
BillTo = 1,
ShipTo = 2,
Primary = 3,
Other = 4
}
public enum Address1_ShippingMethodCode
{
Airborne = 1,
DHL = 2,
FedEx = 3,
UPS = 4,
PostalMail = 5,
FullLoad = 6,
WillCall = 7
}
public enum PaymentTermsCode
{
Net30 = 1,
_210Net30 = 2,
Net45 = 3,
Net60 = 4
}
public enum AccountCategoryCode
{
PreferredCustomer = 1,
Standard = 2
}
public enum Address1_FreightTermsCode
{
FOB = 1,
NoCharge = 2
}
public enum AccountRatingCode
{
DefaultValue = 1
}
public enum PreferredAppointmentTimeCode
{
Morning = 1,
Afternoon = 2,
Evening = 3
}
public enum AccountClassificationCode
{
DefaultValue = 1
}
public enum CustomerTypeCode
{
Competitor = 1,
Consultant = 2,
Customer = 3,
Investor = 4,
Partner = 5,
Influencer = 6,
Press = 7,
Prospect = 8,
Reseller = 9,
Supplier = 10,
Vendor = 11,
Other = 12
}
public enum StatusCode
{
Active = 1,
Inactive = 2
}
public enum OwnershipCode
{
Public = 1,
Private = 2,
Subsidiary = 3,
Other = 4
}
public enum PreferredContactMethodCode
{
Any = 1,
Email = 2,
Phone = 3,
Fax = 4,
Mail = 5
}
public enum TerritoryCode
{
DefaultValue = 1
}
public enum IndustryCode
{
Accounting = 1,
AgricultureAndNonPetrolNaturalResourceExtraction = 2,
BroadcastingPrintingAndPublishing = 3,
Brokers = 4,
BuildingSupplyRetail = 5,
BusinessServices = 6,
Consulting = 7,
ConsumerServices = 8,
DesignDirectionAndCreativeManagement = 9,
DistributorsDispatchersAndProcessors = 10,
DoctorSOfficesAndClinics = 11,
DurableManufacturing = 12,
EatingAndDrinkingPlaces = 13,
EntertainmentRetail = 14,
EquipmentRentalAndLeasing = 15,
Financial = 16,
FoodAndTobaccoProcessing = 17,
InboundCapitalIntensiveProcessing = 18,
InboundRepairAndServices = 19,
Insurance = 20,
LegalServices = 21,
NonDurableMerchandiseRetail = 22,
OutboundConsumerService = 23,
PetrochemicalExtractionAndDistribution = 24,
ServiceRetail = 25,
SIGAffiliations = 26,
SocialServices = 27,
SpecialOutboundTradeContractors = 28,
SpecialtyRealty = 29,
Transportation = 30,
UtilityCreationAndDistribution = 31,
VehicleRetail = 32,
Wholesale = 33
}
public enum BusinessTypeCode
{
DefaultValue = 1
}
public enum ShippingMethodCode
{
DefaultValue = 1
}
public enum Address2_AddressTypeCode
{
DefaultValue = 1
}
public enum CustomerSizeCode
{
DefaultValue = 1
}
public enum Address2_ShippingMethodCode
{
DefaultValue = 1
}
public enum PreferredAppointmentDayCode
{
Sunday = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6
}
public enum Address2_FreightTermsCode
{
DefaultValue = 1
}
public enum StateCode
{
Active = 0,
Inactive = 1
}
}
}
}
using Demo.Entities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Niam.XRM.Framework;
using Niam.XRM.Framework.Data;
using Niam.XRM.Framework.Interfaces.Plugin;
using Niam.XRM.Framework.Plugin;
using StackExchange.Redis;
using System;
using System.Linq;
namespace Demo.Plugin.Business
{
public class GetAccount : OperationBase
{
public GetAccount(ITransactionContext<Entity> context) : base(context)
{
}
protected override void HandleExecute()
{
var cache = new Cache(Context.TracingService, Context.Plugin.UnsecureConfig);
var customers = cache.GetOrAddKey("existing-customer", () =>
{
var data = GetCustomers();
return string.Join(",", data.Select(customer => $"Customers {customer.Id}: {customer.Get(e => e.EMailAddress1)}."));
});
Set("ins_description", customers);
}
private Account[] GetCustomers()
{
var query = new QueryExpression(Account.EntityLogicalName)
{
ColumnSet = new ColumnSet<Account>(e => e.Id, e => e.EMailAddress1)
};
query.Criteria.AddCondition<Account>(e => e.StateCode, ConditionOperator.Equal, (int)Account.Options.StateCode.Active);
query.Criteria.AddCondition<Account>(e => e.EMailAddress1, ConditionOperator.NotNull);
var result = Service.RetrieveMultiple(query);
return result.Entities?.Select(e => e.ToEntity<Account>()).ToArray();
}
}
public class Cache
{
private readonly ITracingService _tracingService;
private readonly string _connectionString;
public Cache(ITracingService tracingService, string connectionString)
{
_tracingService = tracingService;
_connectionString = connectionString;
}
public string GetOrAddKey(string key, Func<string> func)
{
return _tracingService.LogString(() =>
{
var connection = ConnectionMultiplexer.Connect(_connectionString);
var db = connection.GetDatabase();
var cache = db.StringGet(key);
if (!string.IsNullOrEmpty(cache)) return cache;
cache = func.Invoke();
db.StringSet(key, cache);
return cache;
});
}
}
public static class TracingServiceExtension
{
public static string LogString(this ITracingService tracingService, Func<string> func)
{
var start = DateTime.Now;
var result = func.Invoke();
var end = DateTime.Now;
tracingService.Trace(
$"Start: {start}. End: {end}. Total Seconds: {(end - start).TotalSeconds}. Result: {result}.");
return result;
}
}
}
using Demo.Plugin.Business;
using Microsoft.Xrm.Sdk;
using Niam.XRM.Framework.Interfaces.Plugin;
using Niam.XRM.Framework.Plugin;
namespace Demo.Plugin
{
public class PreCacheOperation : PluginBase, IPlugin
{
public PreCacheOperation(string unsecure, string secure) : base(unsecure, secure)
{
}
protected override void ExecuteCrmPlugin(IPluginContext<Entity> context)
{
new GetAccount(context).Execute();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment