private void AddRelationFilter(ShuffleBlocks blocks, string entityName, DataBlockRelation relation, FilterExpression filter, ILoggable log) { log.StartSection(MethodBase.GetCurrentMethod().Name); if (blocks != null && blocks.Count > 0) { var block = relation.Block; var attribute = relation.Attribute; var pkattribute = relation.PKAttribute; var includenull = relation.IncludeNull; var type = GetAttributeType(attribute, entityName); var cond = new ConditionExpression { AttributeName = attribute, Operator = Microsoft.Xrm.Sdk.Query.ConditionOperator.In }; var ids = new List <object>(); var parentcoll = blocks.ContainsKey(block) ? blocks[block] : null; if (parentcoll != null && parentcoll.Count > 0) { foreach (var parent in parentcoll) { if (string.IsNullOrEmpty(pkattribute)) { if (type == AttributeTypeCode.String) { ids.Add(parent.Id.ToString()); } else { ids.Add(parent.Id); } } else if (type == AttributeTypeCode.String) { ids.Add(parent.Property <EntityReference>(pkattribute, new EntityReference()).Id.ToString()); } else { ids.Add(parent.Property <EntityReference>(pkattribute, new EntityReference()).Id); } } } else { // Adding temp guid to indicate "no matches", as ConditionOperator.In will fail if no values are given ids.Add(new Guid()); } cond.Values.AddRange(ids); if (!includenull) { filter.AddCondition(cond); } else { var orfilter = new FilterExpression(LogicalOperator.Or); orfilter.AddCondition(attribute, Microsoft.Xrm.Sdk.Query.ConditionOperator.Null); orfilter.AddCondition(cond); filter.AddFilter(orfilter); } log.Log("Adding relation condition for {0} in {1} values in {2}.{3}", attribute, ids.Count, block, pkattribute); } log.EndSection(); }
/// <summary> /// Deserialize xml/string to blocks with entities /// </summary> /// <param name="serialized"></param> /// <returns>Optional, only required for SerializationType: Text</returns> public ShuffleBlocks Deserialize(XmlDocument serialized) { log.StartSection("Deserialize"); ShuffleBlocks result = new ShuffleBlocks(); if (serialized != null) { XmlNode root = CintXML.FindChild(serialized, "ShuffleData"); string sertype = CintXML.GetAttribute(root, "Type"); SendLine("Deserialize from {0}", sertype); if (sertype == SerializationType.Full.ToString() || sertype == SerializationType.Simple.ToString() || sertype == SerializationType.SimpleNoId.ToString() || sertype == SerializationType.SimpleWithValue.ToString() || sertype == SerializationType.Explicit.ToString()) { foreach (XmlNode xBlock in root.ChildNodes) { if (xBlock.NodeType == XmlNodeType.Element && xBlock.Name == "Block" && xBlock.ChildNodes.Count == 1) { string name = CintXML.GetAttribute(xBlock, "Name"); XmlDocument xml = new XmlDocument(); xml.AppendChild(xml.ImportNode(xBlock.ChildNodes[0], true)); CintDynEntityCollection cEntities = new CintDynEntityCollection(xml, crmsvc, log); SendLine("Block {0}: {1} records", name, cEntities.Count); result.Add(name, cEntities); } } } else if (sertype == SerializationType.Text.ToString()) { string strdelimeter = CintXML.GetAttribute(root, "Delimeter"); char delimeter = strdelimeter.Length == 1 ? strdelimeter[0] : '\t'; XmlNode xText = CintXML.FindChild(root, "Text"); StringReader reader = new StringReader(xText.InnerText); int line = 0; string name = ""; StringBuilder serializedblock = null; string current = reader.ReadLine(); while (current != null) { log.Log("Line {0:000}: {1}", line, current); if (current.StartsWith("<<<") && current.Contains(">>>")) { log.Log("Block start"); if (!string.IsNullOrWhiteSpace(name) && serializedblock != null) { CintDynEntityCollection cEntities = new CintDynEntityCollection(serializedblock.ToString(), delimeter, crmsvc, log); result.Add(name, cEntities); SendLine("Block {0}: {1} records", name, cEntities.Count); } name = current.Substring(3); name = name.Substring(0, name.IndexOf(">>>", StringComparison.Ordinal)); serializedblock = new StringBuilder(); } else { serializedblock.AppendLine(current); } current = reader.ReadLine(); line++; } if (!string.IsNullOrWhiteSpace(serializedblock.ToString())) { CintDynEntityCollection cEntities = new CintDynEntityCollection(serializedblock.ToString(), delimeter, crmsvc, log); result.Add(name, cEntities); SendLine("Block {0}: {1} records", name, cEntities.Count); } } } log.EndSection(); return(result); }
/// <summary> /// Export entities from CRM to dictionary of blocks with entities /// </summary> /// <returns>Blocks with exported entities</returns> public ShuffleBlocks ExportFromCRM() { log.StartSection("ExportFromCRM"); if (definition == null) { throw new ArgumentNullException("Definition", "Shuffle definition must be specified to export data"); } ShuffleBlocks blocks = new ShuffleBlocks(); ExistingSolutionVersions = null; XmlNode xRoot = CintXML.FindChild(definition, "ShuffleDefinition"); XmlNode xBlocks = CintXML.FindChild(xRoot, "Blocks"); if (xBlocks != null) { stoponerror = CintXML.GetBoolAttribute(xRoot, "StopOnError", false); timeout = CintXML.GetIntAttribute(xRoot, "Timeout", -1); double savedtimeout = -1; if (timeout > -1) { SendLine("Setting timeout: {0} minutes", timeout); OrganizationServiceProxy orgsvcpxy = crmsvc.GetService <OrganizationServiceProxy>(); savedtimeout = orgsvcpxy.Timeout.TotalMinutes; orgsvcpxy.Timeout = new TimeSpan(0, timeout, 0); } int totalBlocks = xBlocks.ChildNodes.Count; int currentBlock = 0; foreach (XmlNode xBlock in xBlocks.ChildNodes) { currentBlock++; SendStatus(totalBlocks, currentBlock, -1, -1); if (xBlock.NodeType == XmlNodeType.Element) { switch (xBlock.Name) { case "DataBlock": CintDynEntityCollection cExported = ExportDataBlock(blocks, xBlock); string name = CintXML.GetAttribute(xBlock, "Name"); if (cExported != null) { if (blocks.ContainsKey(name)) { SendLine("Block already added: {0}", name); } else { blocks.Add(name, cExported); } } break; case "SolutionBlock": if (ExistingSolutionVersions == null) { GetCurrentVersions(); } ExportSolutionBlock(xBlock); break; } } } SendStatus(0, 0, 0, 0); if (savedtimeout > -1) { OrganizationServiceProxy orgsvcpxy = crmsvc.GetService <OrganizationServiceProxy>(); orgsvcpxy.Timeout = new TimeSpan(0, (int)savedtimeout, 0); } } log.EndSection(); return(blocks); }