| | 1 | | using FakeXrmEasy.Extensions; |
| | 2 | | using Microsoft.Xrm.Sdk; |
| | 3 | | using Microsoft.Xrm.Sdk.Messages; |
| | 4 | | using Microsoft.Xrm.Sdk.Query; |
| | 5 | | using System; |
| | 6 | | using System.ServiceModel; |
| | 7 | |
|
| | 8 | | namespace FakeXrmEasy.FakeMessageExecutors |
| | 9 | | { |
| | 10 | | public class RetrieveRequestExecutor : IFakeMessageExecutor |
| | 11 | | { |
| | 12 | | public bool CanExecute(OrganizationRequest request) |
| 96 | 13 | | { |
| 96 | 14 | | return request.GetType().Equals(GetResponsibleRequestType()); |
| 96 | 15 | | } |
| | 16 | |
|
| | 17 | |
|
| | 18 | |
|
| | 19 | | public OrganizationResponse Execute(OrganizationRequest req, XrmFakedContext context) |
| 778 | 20 | | { |
| 778 | 21 | | var request = req as RetrieveRequest; |
| | 22 | |
|
| 778 | 23 | | if (request.Target == null) |
| 6 | 24 | | { |
| 6 | 25 | | throw new ArgumentNullException("Target", "RetrieveRequest without Target is invalid."); |
| | 26 | | } |
| | 27 | |
|
| 772 | 28 | | var entityName = request.Target.LogicalName; |
| 772 | 29 | | var columnSet = request.ColumnSet; |
| 772 | 30 | | if (columnSet == null) |
| 6 | 31 | | { |
| 6 | 32 | | throw new FaultException<OrganizationServiceFault>(new OrganizationServiceFault(), "Required field 'Colu |
| | 33 | | } |
| | 34 | |
|
| 766 | 35 | | var id = context.GetRecordUniqueId(request.Target); |
| | 36 | |
|
| | 37 | | //Entity logical name exists, so , check if the requested entity exists |
| 739 | 38 | | if (context.Data.ContainsKey(entityName) && context.Data[entityName] != null |
| 739 | 39 | | && context.Data[entityName].ContainsKey(id)) |
| 703 | 40 | | { |
| | 41 | | //Return the subset of columns requested only |
| 703 | 42 | | var reflectedType = context.FindReflectedType(entityName); |
| | 43 | |
|
| | 44 | | //Entity found => return only the subset of columns specified or all of them |
| 703 | 45 | | var resultEntity = context.Data[entityName][id].Clone(reflectedType, context); |
| 703 | 46 | | if (!columnSet.AllColumns) |
| 152 | 47 | | { |
| 152 | 48 | | resultEntity = resultEntity.ProjectAttributes(columnSet, context); |
| 152 | 49 | | } |
| 703 | 50 | | resultEntity.ApplyDateBehaviour(context); |
| | 51 | |
|
| 703 | 52 | | if (request.RelatedEntitiesQuery != null && request.RelatedEntitiesQuery.Count > 0) |
| 78 | 53 | | { |
| 390 | 54 | | foreach (var relatedEntitiesQuery in request.RelatedEntitiesQuery) |
| 84 | 55 | | { |
| 84 | 56 | | if (relatedEntitiesQuery.Value == null) |
| 6 | 57 | | { |
| 6 | 58 | | throw new ArgumentNullException("relateEntitiesQuery.Value", |
| 6 | 59 | | string.Format("RelatedEntitiesQuery for \"{0}\" does not contain a Query Expression.", |
| 6 | 60 | | relatedEntitiesQuery.Key.SchemaName)); |
| | 61 | | } |
| | 62 | |
|
| 78 | 63 | | var fakeRelationship = context.GetRelationship(relatedEntitiesQuery.Key.SchemaName); |
| 78 | 64 | | if (fakeRelationship == null) |
| 6 | 65 | | { |
| 6 | 66 | | throw new Exception(string.Format("Relationship \"{0}\" does not exist in the metadata cache |
| 6 | 67 | | relatedEntitiesQuery.Key.SchemaName)); |
| | 68 | | } |
| | 69 | |
|
| 72 | 70 | | var relatedEntitiesQueryValue = (QueryExpression)relatedEntitiesQuery.Value; |
| 72 | 71 | | QueryExpression retrieveRelatedEntitiesQuery = relatedEntitiesQueryValue.Clone(); |
| | 72 | |
|
| 72 | 73 | | if (fakeRelationship.RelationshipType == XrmFakedRelationship.enmFakeRelationshipType.OneToMany) |
| 36 | 74 | | { |
| 36 | 75 | | var isFrom1to2 = relatedEntitiesQueryValue.EntityName == fakeRelationship.Entity1LogicalName |
| 36 | 76 | | || request.Target.LogicalName != fakeRelationship.Entity1LogicalName |
| 36 | 77 | | || string.IsNullOrWhiteSpace(relatedEntitiesQueryValue.EntityName); |
| | 78 | |
|
| 36 | 79 | | if (isFrom1to2) |
| 30 | 80 | | { |
| 30 | 81 | | var fromAttribute = isFrom1to2 ? fakeRelationship.Entity1Attribute : fakeRelationship.En |
| 30 | 82 | | var toAttribute = isFrom1to2 ? fakeRelationship.Entity2Attribute : fakeRelationship.Enti |
| | 83 | |
|
| 30 | 84 | | var linkEntity = new LinkEntity |
| 30 | 85 | | { |
| 30 | 86 | | Columns = new ColumnSet(false), |
| 30 | 87 | | LinkFromAttributeName = fromAttribute, |
| 30 | 88 | | LinkFromEntityName = retrieveRelatedEntitiesQuery.EntityName, |
| 30 | 89 | | LinkToAttributeName = toAttribute, |
| 30 | 90 | | LinkToEntityName = resultEntity.LogicalName |
| 30 | 91 | | }; |
| | 92 | |
|
| 30 | 93 | | if (retrieveRelatedEntitiesQuery.Criteria == null) |
| 0 | 94 | | { |
| 0 | 95 | | retrieveRelatedEntitiesQuery.Criteria = new FilterExpression(); |
| 0 | 96 | | } |
| | 97 | |
|
| 30 | 98 | | retrieveRelatedEntitiesQuery.Criteria |
| 30 | 99 | | .AddFilter(LogicalOperator.And) |
| 30 | 100 | | .AddCondition(linkEntity.LinkFromAttributeName, ConditionOperator.Equal, resultEntit |
| 30 | 101 | | } |
| | 102 | | else |
| 6 | 103 | | { |
| 6 | 104 | | var link = retrieveRelatedEntitiesQuery.AddLink(fakeRelationship.Entity1LogicalName, fak |
| 6 | 105 | | link.LinkCriteria.AddCondition(resultEntity.LogicalName + "id", ConditionOperator.Equal, |
| 6 | 106 | | } |
| 36 | 107 | | } |
| | 108 | | else |
| 36 | 109 | | { |
| 36 | 110 | | var isFrom1 = fakeRelationship.Entity1LogicalName == retrieveRelatedEntitiesQuery.EntityName |
| 36 | 111 | | var linkAttributeName = isFrom1 ? fakeRelationship.Entity1Attribute : fakeRelationship.Entit |
| 36 | 112 | | var conditionAttributeName = isFrom1 ? fakeRelationship.Entity2Attribute : fakeRelationship. |
| | 113 | |
|
| 36 | 114 | | var linkEntity = new LinkEntity |
| 36 | 115 | | { |
| 36 | 116 | | Columns = new ColumnSet(false), |
| 36 | 117 | | LinkFromAttributeName = linkAttributeName, |
| 36 | 118 | | LinkFromEntityName = retrieveRelatedEntitiesQuery.EntityName, |
| 36 | 119 | | LinkToAttributeName = linkAttributeName, |
| 36 | 120 | | LinkToEntityName = fakeRelationship.IntersectEntity, |
| 36 | 121 | | LinkCriteria = new FilterExpression |
| 36 | 122 | | { |
| 36 | 123 | | Conditions = |
| 36 | 124 | | { |
| 36 | 125 | | new ConditionExpression(conditionAttributeName , ConditionOperator.Equal, resultEnti |
| 36 | 126 | | } |
| 36 | 127 | | } |
| 36 | 128 | | }; |
| 36 | 129 | | retrieveRelatedEntitiesQuery.LinkEntities.Add(linkEntity); |
| 36 | 130 | | } |
| | 131 | |
|
| 72 | 132 | | var retrieveRelatedEntitiesRequest = new RetrieveMultipleRequest |
| 72 | 133 | | { |
| 72 | 134 | | Query = retrieveRelatedEntitiesQuery |
| 72 | 135 | | }; |
| | 136 | |
|
| | 137 | | //use of an executor directly; if to use service.RetrieveMultiple then the result will be |
| | 138 | | //limited to the number of records per page (somewhere in future release). |
| | 139 | | //ALL RECORDS are needed here. |
| 72 | 140 | | var executor = new RetrieveMultipleRequestExecutor(); |
| 72 | 141 | | var retrieveRelatedEntitiesResponse = executor |
| 72 | 142 | | .Execute(retrieveRelatedEntitiesRequest, context) as RetrieveMultipleResponse; |
| | 143 | |
|
| 72 | 144 | | if (retrieveRelatedEntitiesResponse.EntityCollection.Entities.Count == 0) |
| 0 | 145 | | continue; |
| | 146 | |
|
| 72 | 147 | | resultEntity.RelatedEntities |
| 72 | 148 | | .Add(relatedEntitiesQuery.Key, retrieveRelatedEntitiesResponse.EntityCollection); |
| 72 | 149 | | } |
| 66 | 150 | | } |
| | 151 | |
|
| 691 | 152 | | return new RetrieveResponse |
| 691 | 153 | | { |
| 691 | 154 | | Results = new ParameterCollection { { "Entity", resultEntity } } |
| 691 | 155 | | }; |
| | 156 | | } |
| | 157 | | else |
| 36 | 158 | | { |
| | 159 | | // Entity not found in the context => FaultException |
| 36 | 160 | | throw new FaultException<OrganizationServiceFault>(new OrganizationServiceFault() { ErrorCode = unchecke |
| | 161 | | } |
| 691 | 162 | | } |
| | 163 | |
|
| | 164 | | public Type GetResponsibleRequestType() |
| 4366 | 165 | | { |
| 4366 | 166 | | return typeof(RetrieveRequest); |
| 4366 | 167 | | } |
| | 168 | | } |
| | 169 | | } |