static void ThrowClientFault(string code, string message, params object[] args) { message = StringHelper.SafeFormat(message, args); var fault = new ClientFault() { Code = code, Message = message }; var ex = new ClientFaultException(new [] { fault }); throw ex; }
private static void WriteClientFaultException(StringBuilder sb, ClientFaultException exception) { sb.AppendFormat("ClientFaultException: {0}\r\n", exception.Message); foreach (var fault in exception.Faults) { sb.Append(" "); sb.AppendLine(fault.ToLogString()); } if (exception.Data.Count > 0) { WriteExceptionData(sb, exception); } if (exception.InnerException != null) { WriteInnerException(sb, exception.InnerException); } }
//Sequences set of records in a looped non-trivial entity group. Assigns record.SortSubIndex value after sequencing private void SequenceSubGroup(IEnumerable <EntityRecord> records) { var graph = new Graph(); foreach (var rec in records) { var ent = rec.EntityInfo; foreach (var refMember in ent.RefMembers) { var targetEnt = rec.GetValue(refMember); //If reference is not modified or not set, then nothing to do if (targetEnt == null) { continue; } var targetRec = EntityHelper.GetRecord(targetEnt); // we are interested only in case when both records are inserted, or both are deleted. if (targetRec.Status != rec.Status) { continue; } // finally, the target record's table must be in the same SCC group - i.e. have the same SccIndex if (targetRec.EntityInfo.TopologicalIndex != rec.EntityInfo.TopologicalIndex) { continue; } // We have potential conflict; add vertexes and link for the conflict var thisV = graph.FindOrAdd(rec); var targetV = graph.FindOrAdd(targetRec); thisV.AddLink(targetV); } }//foreach cmd //Check if any conflicts found if (graph.Vertexes.Count == 0) { return; } //Build SCC graph graph.BuildScc(); // Once SCC is built, we have SCC indexes in Vertexes; use them to assign Record's TopologicalIndex bool hasNonTrivialGroups = false; foreach (var v in graph.Vertexes) { var rec = (EntityRecord)v.Tag; rec.SortSubIndex = rec.Status == EntityStatus.New ? -v.SccIndex : v.SccIndex; hasNonTrivialGroups |= v.NonTrivialGroup; } //if there are non-trivial groups, it means we have circular references in the set. if (hasNonTrivialGroups) { var entList = string.Join(",", records.Select(r => r.PrimaryKey.ToString())); var msg = StringHelper.SafeFormat("Detected circular references between entities in an update set. Cannot commit group update. Entities: [{0}].", entList); var fault = new ClientFault() { Code = ClientFaultCodes.CircularEntityReference, Message = msg }; var faultEx = new ClientFaultException(new[] { fault }); faultEx.LogAsError = true; throw faultEx; } }