From 504e9f915af570f4a69180efb8e61c978d28cfc8 Mon Sep 17 00:00:00 2001 From: Jordi Date: Tue, 30 Jul 2019 09:49:34 +0200 Subject: [PATCH] Updated version --- DevToolkitSamples/Properties/AssemblyInfo.cs | 4 +- FakeXrmEasy.2013/Properties/AssemblyInfo.cs | 4 +- FakeXrmEasy.2015/Properties/AssemblyInfo.cs | 4 +- FakeXrmEasy.2016/Properties/AssemblyInfo.cs | 4 +- FakeXrmEasy.365/Properties/AssemblyInfo.cs | 4 +- FakeXrmEasy.9/Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- FakeXrmEasy.Tests/Properties/AssemblyInfo.cs | 4 +- FakeXrmEasy/Properties/AssemblyInfo.cs | 6 +- Install-scripts/2011/Install.ps1 | 2 +- Install-scripts/2013/Install.ps1 | 2 +- Install-scripts/2015/Install.ps1 | 2 +- Install-scripts/2016/Install.ps1 | 2 +- Install-scripts/365/Install.ps1 | 2 +- Install-scripts/9/Install.ps1 | 2 +- README.md | 14 +- build.fsx | 4 +- .../FakeXrmEasy_AccessRightsRepository.htm | 10 +- ...Easy_AddListMembersListRequestExecutor.htm | 8 +- ...keXrmEasy_AddMemberListRequestExecutor.htm | 8 +- ...eXrmEasy_AddMembersTeamRequestExecutor.htm | 8 +- .../FakeXrmEasy_AddToQueueRequestExecutor.htm | 8 +- ...asy_AddUserToRecordTeamRequestExecutor.htm | 8 +- test/reports/FakeXrmEasy_ArrayExtensions.htm | 14 +- test/reports/FakeXrmEasy_ArrayTraverse.htm | 42 +- .../FakeXrmEasy_AssignRequestExecutor.htm | 8 +- .../FakeXrmEasy_AssociateRequestExecutor.htm | 90 +- .../FakeXrmEasy_BulkDeleteRequestExecutor.htm | 8 +- ...keXrmEasy_CloseIncidentRequestExecutor.htm | 8 +- .../FakeXrmEasy_CloseQuoteRequestExecutor.htm | 8 +- .../FakeXrmEasy_CreateRequestExecutor.htm | 8 +- .../FakeXrmEasy_DateTimeExtensions.htm | 2 +- ...rmEasy_DefaultEntityInitializerService.htm | 60 +- .../FakeXrmEasy_DeleteRequestExecutor.htm | 8 +- ...akeXrmEasy_DisassociateRequestExecutor.htm | 8 +- test/reports/FakeXrmEasy_EntityExtensions.htm | 394 +- .../FakeXrmEasy_EntityMetadataExtensions.htm | 30 +- .../FakeXrmEasy_EntityReferenceExtensions.htm | 2 +- ...akeXrmEasy_ExecuteFetchRequestExecutor.htm | 10 +- ...XrmEasy_ExecuteMultipleRequestExecutor.htm | 8 +- ...FakeXrmEasy_ExecuteTransactionExecutor.htm | 8 +- ...FakeXrmEasy_GrantAccessRequestExecutor.htm | 8 +- ...eXrmEasy_InitializeFromRequestExecutor.htm | 8 +- ...mEasy_InsertOptionValueRequestExecutor.htm | 8 +- ...mEasy_InsertStatusValueRequestExecutor.htm | 8 +- ...rmEasy_InvoiceDetailInitializerService.htm | 2 +- .../FakeXrmEasy_InvoiceInitializerService.htm | 2 +- ...XrmEasy_LoseOpportunityRequestExecutor.htm | 8 +- .../reports/FakeXrmEasy_MetadataGenerator.htm | 16 +- ...akeXrmEasy_ModifyAccessRequestExecutor.htm | 8 +- ...oNextEntityOrganizationRequestExecutor.htm | 8 +- test/reports/FakeXrmEasy_ObjectExtensions.htm | 98 +- ...rganizationServiceFaultInvalidArgument.htm | 2 +- ...erviceFaultOperatorIsNotValidException.htm | 2 +- ...eFaultQueryBuilderNoAttributeException.htm | 2 +- ...keXrmEasy_PickFromQueueRequestExecutor.htm | 8 +- .../FakeXrmEasy_PublishXmlRequestExecutor.htm | 8 +- .../FakeXrmEasy_PullRequestException.htm | 2 +- ...FakeXrmEasy_QualifyLeadRequestExecutor.htm | 8 +- .../FakeXrmEasy_QueryExpressionExtensions.htm | 8 +- .../FakeXrmEasy_ReferenceEqualityComparer.htm | 16 +- ...XrmEasy_RemoveFromQueueRequestExecutor.htm | 8 +- ...mEasy_RemoveMembersTeamRequestExecutor.htm | 8 +- ...emoveUserFromRecordTeamRequestExecutor.htm | 8 +- ...mEasy_RetrieveAttributeRequestExecutor.htm | 8 +- ...eXrmEasy_RetrieveEntityRequestExecutor.htm | 8 +- ...sy_RetrieveExchangeRateRequestExecutor.htm | 8 +- ...rmEasy_RetrieveMultipleRequestExecutor.htm | 164 +- ...mEasy_RetrieveOptionSetRequestExecutor.htm | 8 +- ...RetrievePrincipalAccessRequestExecutor.htm | 8 +- ...sy_RetrieveRelationshipRequestExecutor.htm | 8 +- .../FakeXrmEasy_RetrieveRequestExecutor.htm | 8 +- ...aredPrincipalsAndAccessRequestExecutor.htm | 8 +- ...XrmEasy_RetrieveVersionRequestExecutor.htm | 8 +- ...FakeXrmEasy_ReviseQuoteRequestExecutor.htm | 8 +- ...akeXrmEasy_RevokeAccessRequestExecutor.htm | 8 +- .../FakeXrmEasy_SendEmailRequestExecutor.htm | 8 +- .../FakeXrmEasy_SetStateRequestExecutor.htm | 8 +- test/reports/FakeXrmEasy_TypeExtensions.htm | 14 +- .../FakeXrmEasy_TypedConditionExpression.htm | 18 +- .../FakeXrmEasy_UpdateRequestExecutor.htm | 8 +- .../FakeXrmEasy_UpsertRequestExecutor.htm | 8 +- .../FakeXrmEasy_WhoAmIRequestExecutor.htm | 8 +- ...eXrmEasy_WinOpportunityRequestExecutor.htm | 8 +- .../FakeXrmEasy_XmlExtensionsForFetchXml.htm | 442 +- test/reports/FakeXrmEasy_XrmFakedContext.htm | 4230 +++++++++-------- ...XrmEasy_XrmFakedPluginExecutionContext.htm | 2 +- .../FakeXrmEasy_XrmFakedRelationship.htm | 153 +- .../FakeXrmEasy_XrmFakedTracingService.htm | 2 +- .../FakeXrmEasy_XrmFakedWorkflowContext.htm | 2 +- ...akeXrmEasy_XrmOrderByAttributeComparer.htm | 2 +- test/reports/FakeXrmEasy_XrmRealContext.htm | 2 +- test/reports/badge_branchcoverage.svg | 2 +- test/reports/badge_combined.svg | 4 +- test/reports/badge_linecoverage.svg | 2 +- test/reports/combined.js | 8 +- test/reports/index.htm | 26 +- 101 files changed, 3229 insertions(+), 3084 deletions(-) diff --git a/DevToolkitSamples/Properties/AssemblyInfo.cs b/DevToolkitSamples/Properties/AssemblyInfo.cs index 76cd4c21..0fdb44da 100644 --- a/DevToolkitSamples/Properties/AssemblyInfo.cs +++ b/DevToolkitSamples/Properties/AssemblyInfo.cs @@ -34,5 +34,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.2013/Properties/AssemblyInfo.cs b/FakeXrmEasy.2013/Properties/AssemblyInfo.cs index 9d8651ae..de1380ce 100644 --- a/FakeXrmEasy.2013/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.2013/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.2015/Properties/AssemblyInfo.cs b/FakeXrmEasy.2015/Properties/AssemblyInfo.cs index 85db893f..e44024a5 100644 --- a/FakeXrmEasy.2015/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.2015/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.2016/Properties/AssemblyInfo.cs b/FakeXrmEasy.2016/Properties/AssemblyInfo.cs index bba9c752..56bf5fbf 100644 --- a/FakeXrmEasy.2016/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.2016/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.365/Properties/AssemblyInfo.cs b/FakeXrmEasy.365/Properties/AssemblyInfo.cs index ebb4b360..a081d316 100644 --- a/FakeXrmEasy.365/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.365/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.9/Properties/AssemblyInfo.cs b/FakeXrmEasy.9/Properties/AssemblyInfo.cs index b0ed3e7d..5558f524 100644 --- a/FakeXrmEasy.9/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.9/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.Tests.2013/Properties/AssemblyInfo.cs b/FakeXrmEasy.Tests.2013/Properties/AssemblyInfo.cs index f4aeaa16..76d3b1ed 100644 --- a/FakeXrmEasy.Tests.2013/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.Tests.2013/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.Tests.2015/Properties/AssemblyInfo.cs b/FakeXrmEasy.Tests.2015/Properties/AssemblyInfo.cs index 813a06fb..738f9991 100644 --- a/FakeXrmEasy.Tests.2015/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.Tests.2015/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.Tests.2016/Properties/AssemblyInfo.cs b/FakeXrmEasy.Tests.2016/Properties/AssemblyInfo.cs index 6292c7a3..73771af8 100644 --- a/FakeXrmEasy.Tests.2016/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.Tests.2016/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.Tests.365/Properties/AssemblyInfo.cs b/FakeXrmEasy.Tests.365/Properties/AssemblyInfo.cs index 1d195cee..c3777831 100644 --- a/FakeXrmEasy.Tests.365/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.Tests.365/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.Tests.9/Properties/AssemblyInfo.cs b/FakeXrmEasy.Tests.9/Properties/AssemblyInfo.cs index f5c6534f..788b46b6 100644 --- a/FakeXrmEasy.Tests.9/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.Tests.9/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy.Tests/Properties/AssemblyInfo.cs b/FakeXrmEasy.Tests/Properties/AssemblyInfo.cs index f2aea10d..4c945d27 100644 --- a/FakeXrmEasy.Tests/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy.Tests/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.44.0.0")] -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] diff --git a/FakeXrmEasy/Properties/AssemblyInfo.cs b/FakeXrmEasy/Properties/AssemblyInfo.cs index 0c18f79f..4da7e522 100644 --- a/FakeXrmEasy/Properties/AssemblyInfo.cs +++ b/FakeXrmEasy/Properties/AssemblyInfo.cs @@ -30,6 +30,6 @@ // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("1.54.0.0")] -[assembly: AssemblyFileVersion("1.54.0.0")] -[assembly: AssemblyInformationalVersion("1.54.0.0 - master - 242c73")] +[assembly: AssemblyVersion("1.55.0.0")] +[assembly: AssemblyFileVersion("1.55.0.0")] +[assembly: AssemblyInformationalVersion("1.55.0.0 - master - b93239")] diff --git a/Install-scripts/2011/Install.ps1 b/Install-scripts/2011/Install.ps1 index f0e90bb2..d02fdb26 100644 --- a/Install-scripts/2011/Install.ps1 +++ b/Install-scripts/2011/Install.ps1 @@ -1,4 +1,4 @@ param($installPath, $toolsPath, $package, $project) -$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-2011?version=1.54.0") +$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-2011?version=1.55.0") diff --git a/Install-scripts/2013/Install.ps1 b/Install-scripts/2013/Install.ps1 index bf162249..be748156 100644 --- a/Install-scripts/2013/Install.ps1 +++ b/Install-scripts/2013/Install.ps1 @@ -1,3 +1,3 @@ param($installPath, $toolsPath, $package, $project) -$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-2013?version=1.54.0") +$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-2013?version=1.55.0") diff --git a/Install-scripts/2015/Install.ps1 b/Install-scripts/2015/Install.ps1 index aca78473..db65841c 100644 --- a/Install-scripts/2015/Install.ps1 +++ b/Install-scripts/2015/Install.ps1 @@ -1,4 +1,4 @@ param($installPath, $toolsPath, $package, $project) -$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-2015?version=1.54.0") +$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-2015?version=1.55.0") diff --git a/Install-scripts/2016/Install.ps1 b/Install-scripts/2016/Install.ps1 index a048b44c..cd95c5c0 100644 --- a/Install-scripts/2016/Install.ps1 +++ b/Install-scripts/2016/Install.ps1 @@ -1,4 +1,4 @@ param($installPath, $toolsPath, $package, $project) -$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-2016?version=1.54.0") +$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-2016?version=1.55.0") diff --git a/Install-scripts/365/Install.ps1 b/Install-scripts/365/Install.ps1 index 02661090..29a27257 100644 --- a/Install-scripts/365/Install.ps1 +++ b/Install-scripts/365/Install.ps1 @@ -1,4 +1,4 @@ param($installPath, $toolsPath, $package, $project) -$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-365?version=1.54.0") +$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-365?version=1.55.0") diff --git a/Install-scripts/9/Install.ps1 b/Install-scripts/9/Install.ps1 index b90927c6..2b57ed24 100644 --- a/Install-scripts/9/Install.ps1 +++ b/Install-scripts/9/Install.ps1 @@ -1,4 +1,4 @@ param($installPath, $toolsPath, $package, $project) -$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-9?version=1.54.0") +$DTE.ItemOperations.Navigate("http://dynamicsvalue.com/get-started/nuget-install-9?version=1.55.0") diff --git a/README.md b/README.md index d9b96abd..b445ea0b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ |Build|Line Coverage|Branch Coverage| |-----------|-----|-----------------| -|[![Build status](https://ci.appveyor.com/api/projects/status/2g8yc8jg817746du?svg=true)](https://ci.appveyor.com/project/Jordi/fake-xrm-easy)|[![Line coverage](https://cdn.rawgit.com/jordimontana82/fake-xrm-easy/master/test/reports/badge_linecoverage.svg?v=1.54.0)](https://cdn.rawgit.com/jordimontana82/fake-xrm-easy/master/test/reports/index.htm?v=1.54.0)|[![Branch coverage](https://cdn.rawgit.com/jordimontana82/fake-xrm-easy/master/test/reports/badge_branchcoverage.svg?v=1.54.0)](https://cdn.rawgit.com/jordimontana82/fake-xrm-easy/master/test/reports/index.htm?v=1.54.0)| +|[![Build status](https://ci.appveyor.com/api/projects/status/2g8yc8jg817746du?svg=true)](https://ci.appveyor.com/project/Jordi/fake-xrm-easy)|[![Line coverage](https://cdn.rawgit.com/jordimontana82/fake-xrm-easy/master/test/reports/badge_linecoverage.svg?v=1.55.0)](https://cdn.rawgit.com/jordimontana82/fake-xrm-easy/master/test/reports/index.htm?v=1.55.0)|[![Branch coverage](https://cdn.rawgit.com/jordimontana82/fake-xrm-easy/master/test/reports/badge_branchcoverage.svg?v=1.55.0)](https://cdn.rawgit.com/jordimontana82/fake-xrm-easy/master/test/reports/index.htm?v=1.55.0)| Streamline unit testing in Dynamics CRM by faking the `IOrganizationService` to work with an in-memory context. @@ -14,12 +14,12 @@ |Version|NuGet| |-----------|-----| -|Dynamics v9|[![Nuget](https://buildstats.info/nuget/fakexrmeasy.9?v=1.54.0)](https://www.nuget.org/packages/fakexrmeasy.9)| -|Dynamics 365|[![Nuget](https://buildstats.info/nuget/fakexrmeasy.365?v=1.54.0)](https://www.nuget.org/packages/fakexrmeasy.365)| -|Dynamics CRM 2016|[![Nuget](https://buildstats.info/nuget/fakexrmeasy.2016?v=1.54.0)](https://www.nuget.org/packages/fakexrmeasy.2016)| -|Dynamics CRM 2015|[![Nuget](https://buildstats.info/nuget/fakexrmeasy.2015?v=1.54.0)](https://www.nuget.org/packages/fakexrmeasy.2015)| -|Dynamics CRM 2013|[![Nuget](https://buildstats.info/nuget/fakexrmeasy.2013?v=1.54.0)](https://www.nuget.org/packages/fakexrmeasy.2013)| -|Dynamics CRM 2011|[![Nuget](https://buildstats.info/nuget/fakexrmeasy?v=1.54.0)](https://www.nuget.org/packages/fakexrmeasy)| +|Dynamics v9|[![Nuget](https://buildstats.info/nuget/fakexrmeasy.9?v=1.55.0)](https://www.nuget.org/packages/fakexrmeasy.9)| +|Dynamics 365|[![Nuget](https://buildstats.info/nuget/fakexrmeasy.365?v=1.55.0)](https://www.nuget.org/packages/fakexrmeasy.365)| +|Dynamics CRM 2016|[![Nuget](https://buildstats.info/nuget/fakexrmeasy.2016?v=1.55.0)](https://www.nuget.org/packages/fakexrmeasy.2016)| +|Dynamics CRM 2015|[![Nuget](https://buildstats.info/nuget/fakexrmeasy.2015?v=1.55.0)](https://www.nuget.org/packages/fakexrmeasy.2015)| +|Dynamics CRM 2013|[![Nuget](https://buildstats.info/nuget/fakexrmeasy.2013?v=1.55.0)](https://www.nuget.org/packages/fakexrmeasy.2013)| +|Dynamics CRM 2011|[![Nuget](https://buildstats.info/nuget/fakexrmeasy?v=1.55.0)](https://www.nuget.org/packages/fakexrmeasy)| Supports Dynamics CRM 2011, 2013, 2015, 2016, and Dynamics 365 (8.x and 9.x). NOTE: With the release of Dynamics 365 v9 we are changing the naming convention for new packages to match the major version. diff --git a/build.fsx b/build.fsx index 68803965..1945f09c 100644 --- a/build.fsx +++ b/build.fsx @@ -48,8 +48,8 @@ let nugetDeployDir = @"[Enter_NuGet_Url]" let packagesDir = @".\packages\" let nuGetCommandLine = @".\tools\nuget\nuget410.exe" -let mutable previousVersion = "1.53.0" -let mutable version = "1.54.0" //Copy this into previousVersion before publishing packages... +let mutable previousVersion = "1.54.0" +let mutable version = "1.55.0" //Copy this into previousVersion before publishing packages... let mutable build = buildVersion let mutable nugetVersion = version let mutable asmVersion = version diff --git a/test/reports/FakeXrmEasy_AccessRightsRepository.htm b/test/reports/FakeXrmEasy_AccessRightsRepository.htm index b0efaf7e..c70134fe 100644 --- a/test/reports/FakeXrmEasy_AccessRightsRepository.htm +++ b/test/reports/FakeXrmEasy_AccessRightsRepository.htm @@ -54,11 +54,11 @@

D:\  10    {  11        protected Dictionary<EntityReference, List<PrincipalAccess>> _accessRights;  12 - 400013        public AccessRightsRepository() - 400014        { + 405013        public AccessRightsRepository() + 405014        {  15            //One record might be accessed from many security principals - 400016            _accessRights = new Dictionary<EntityReference, List<PrincipalAccess>>(); - 400017        } + 405016            _accessRights = new Dictionary<EntityReference, List<PrincipalAccess>>(); + 405017        }  18  19        /// <summary>  20        /// Grants the specified rights to the security principal (user or team) for the specified record @@ -167,6 +167,6 @@

D:\  123} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_AddListMembersListRequestExecutor.htm b/test/reports/FakeXrmEasy_AddListMembersListRequestExecutor.htm index 95b839b7..788e4c45 100644 --- a/test/reports/FakeXrmEasy_AddListMembersListRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_AddListMembersListRequestExecutor.htm @@ -139,13 +139,13 @@

 18100        }  101  102        public Type GetResponsibleRequestType() - 4000103        { - 4000104            return typeof(AddListMembersListRequest); - 4000105        } + 4050103        { + 4050104            return typeof(AddListMembersListRequest); + 4050105        }  106    }  107} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_AddMemberListRequestExecutor.htm b/test/reports/FakeXrmEasy_AddMemberListRequestExecutor.htm index 1d4a5cbc..52e1fc9e 100644 --- a/test/reports/FakeXrmEasy_AddMemberListRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_AddMemberListRequestExecutor.htm @@ -135,13 +135,13 @@

 1896        }  97  98        public Type GetResponsibleRequestType() - 400099        { - 4000100            return typeof(AddMemberListRequest); - 4000101        } + 405099        { + 4050100            return typeof(AddMemberListRequest); + 4050101        }  102    }  103} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_AddMembersTeamRequestExecutor.htm b/test/reports/FakeXrmEasy_AddMembersTeamRequestExecutor.htm index ef9d1dfb..6f58dfa9 100644 --- a/test/reports/FakeXrmEasy_AddMembersTeamRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_AddMembersTeamRequestExecutor.htm @@ -95,13 +95,13 @@

 656        }  57  58        public Type GetResponsibleRequestType() - 400059        { - 400060            return typeof(AddMembersTeamRequest); - 400061        } + 405059        { + 405060            return typeof(AddMembersTeamRequest); + 405061        }  62    }  63} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_AddToQueueRequestExecutor.htm b/test/reports/FakeXrmEasy_AddToQueueRequestExecutor.htm index 900eb632..a68c6e1f 100644 --- a/test/reports/FakeXrmEasy_AddToQueueRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_AddToQueueRequestExecutor.htm @@ -107,13 +107,13 @@

 1868        }  69  70        public Type GetResponsibleRequestType() - 400071        { - 400072            return typeof(AddToQueueRequest); - 400073        } + 405071        { + 405072            return typeof(AddToQueueRequest); + 405073        }  74    }  75} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_AddUserToRecordTeamRequestExecutor.htm b/test/reports/FakeXrmEasy_AddUserToRecordTeamRequestExecutor.htm index b8c3ed22..06336dea 100644 --- a/test/reports/FakeXrmEasy_AddUserToRecordTeamRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_AddUserToRecordTeamRequestExecutor.htm @@ -129,14 +129,14 @@

 590        }  91  92        public Type GetResponsibleRequestType() - 336293        { - 336294            return typeof(AddUserToRecordTeamRequest); - 336295        } + 340793        { + 340794            return typeof(AddUserToRecordTeamRequest); + 340795        }  96    }  97}  98#endif - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_ArrayExtensions.htm b/test/reports/FakeXrmEasy_ArrayExtensions.htm index c8db6c3d..5e107425 100644 --- a/test/reports/FakeXrmEasy_ArrayExtensions.htm +++ b/test/reports/FakeXrmEasy_ArrayExtensions.htm @@ -166,12 +166,12 @@

D:\Git\fak  129    public static class ArrayExtensions  130    {  131        public static void ForEach(this Array array, Action<Array, int[]> action) - 22102132        { - 22235133             if (array.LongLength == 0) return; - 21969134            ArrayTraverse walker = new ArrayTraverse(array); - 310028135            do action(array, walker.Position); - 310028136             while (walker.Step()); - 22102137        } + 18034132        { + 18179133             if (array.LongLength == 0) return; + 17889134            ArrayTraverse walker = new ArrayTraverse(array); + 239864135            do action(array, walker.Position); + 239864136             while (walker.Step()); + 18034137        }  138    }  139  140    internal class ArrayTraverse @@ -209,6 +209,6 @@

D:\Git\fak  172} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_ArrayTraverse.htm b/test/reports/FakeXrmEasy_ArrayTraverse.htm index d280754a..d8097066 100644 --- a/test/reports/FakeXrmEasy_ArrayTraverse.htm +++ b/test/reports/FakeXrmEasy_ArrayTraverse.htm @@ -180,36 +180,36 @@

D:\Git\fak  142        public int[] Position;  143        private int[] maxLengths;  144 - 21969145        public ArrayTraverse(Array array) - 21969146        { - 21969147            maxLengths = new int[array.Rank]; - 87876148             for (int i = 0; i < array.Rank; ++i) - 21969149            { - 21969150                maxLengths[i] = array.GetLength(i) - 1; - 21969151            } - 21969152            Position = new int[array.Rank]; - 21969153        } + 17889145        public ArrayTraverse(Array array) + 17889146        { + 17889147            maxLengths = new int[array.Rank]; + 71556148             for (int i = 0; i < array.Rank; ++i) + 17889149            { + 17889150                maxLengths[i] = array.GetLength(i) - 1; + 17889151            } + 17889152            Position = new int[array.Rank]; + 17889153        }  154  155        public bool Step() - 310028156        { - 663994157             for (int i = 0; i < Position.Length; ++i) - 310028158            { - 310028159                 if (Position[i] < maxLengths[i]) - 288059160                { - 288059161                    Position[i]++; - 576118162                     for (int j = 0; j < i; j++) + 239864156        { + 515506157             for (int i = 0; i < Position.Length; ++i) + 239864158            { + 239864159                 if (Position[i] < maxLengths[i]) + 221975160                { + 221975161                    Position[i]++; + 443950162                     for (int j = 0; j < i; j++)  0163                    {  0164                        Position[j] = 0;  0165                    } - 288059166                    return true; + 221975166                    return true;  167                } - 21969168            } - 21969169            return false; - 310028170        } + 17889168            } + 17889169            return false; + 239864170        }  171    }  172} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_AssignRequestExecutor.htm b/test/reports/FakeXrmEasy_AssignRequestExecutor.htm index fb0f422a..5d7dc703 100644 --- a/test/reports/FakeXrmEasy_AssignRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_AssignRequestExecutor.htm @@ -94,13 +94,13 @@

 1855        }  56  57        public Type GetResponsibleRequestType() - 400058        { - 400059            return typeof(AssignRequest); - 400060        } + 405058        { + 405059            return typeof(AssignRequest); + 405060        }  61    }  62} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_AssociateRequestExecutor.htm b/test/reports/FakeXrmEasy_AssociateRequestExecutor.htm index d54e5a59..71eca073 100644 --- a/test/reports/FakeXrmEasy_AssociateRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_AssociateRequestExecutor.htm @@ -52,71 +52,71 @@

 3613        }  14  15        public OrganizationResponse Execute(OrganizationRequest request, XrmFakedContext ctx) - 16816        { - 16817            var associateRequest = request as AssociateRequest; - 16818            var service = ctx.GetFakedOrganizationService(); + 18016        { + 18017            var associateRequest = request as AssociateRequest; + 18018            var service = ctx.GetFakedOrganizationService();  19 - 16820             if (associateRequest == null) + 18020             if (associateRequest == null)  621            {  622                throw new Exception("Only associate request can be processed!");  23            }  24 - 16225            var associateRelationship = associateRequest.Relationship; - 16226            var relationShipName = associateRelationship.SchemaName; - 16227            var fakeRelationShip = ctx.GetRelationship(relationShipName); + 17425            var associateRelationship = associateRequest.Relationship; + 17426            var relationShipName = associateRelationship.SchemaName; + 17427            var fakeRelationShip = ctx.GetRelationship(relationShipName);  28 - 16229             if (fakeRelationShip == null) + 17429             if (fakeRelationShip == null)  630            {  631                throw new Exception(string.Format("Relationship {0} does not exist in the metadata cache", relationShipN  32            }  33 - 15634             if (associateRequest.Target == null) + 16834             if (associateRequest.Target == null)  635            {  636                throw new Exception("Association without target is invalid!");  37            }  38 - 143439            foreach (var relatedEntityReference in associateRequest.RelatedEntities) - 49840            { - 49841                 if (fakeRelationShip.RelationshipType == XrmFakedRelationship.enmFakeRelationshipType.ManyToMany) - 48642                { - 48643                    var isFrom1to2 = associateRequest.Target.LogicalName == fakeRelationShip.Entity1LogicalName - 48644                                         || relatedEntityReference.LogicalName != fakeRelationShip.Entity1LogicalName - 48645                                         || String.IsNullOrWhiteSpace(associateRequest.Target.LogicalName); - 48646                     var fromAttribute = isFrom1to2 ? fakeRelationShip.Entity1Attribute : fakeRelationShip.Entity2Attribu - 48647                     var toAttribute = isFrom1to2 ? fakeRelationShip.Entity2Attribute : fakeRelationShip.Entity1Attribute - 48648                     var fromEntityName = isFrom1to2 ? fakeRelationShip.Entity1LogicalName : fakeRelationShip.Entity2Logi - 48649                     var toEntityName = isFrom1to2 ? fakeRelationShip.Entity2LogicalName : fakeRelationShip.Entity1Logica + 149439            foreach (var relatedEntityReference in associateRequest.RelatedEntities) + 51040            { + 51041                 if (fakeRelationShip.RelationshipType == XrmFakedRelationship.enmFakeRelationshipType.ManyToMany) + 49842                { + 49843                    var isFrom1to2 = associateRequest.Target.LogicalName == fakeRelationShip.Entity1LogicalName + 49844                                         || relatedEntityReference.LogicalName != fakeRelationShip.Entity1LogicalName + 49845                                         || String.IsNullOrWhiteSpace(associateRequest.Target.LogicalName); + 49846                     var fromAttribute = isFrom1to2 ? fakeRelationShip.Entity1Attribute : fakeRelationShip.Entity2Attribu + 49847                     var toAttribute = isFrom1to2 ? fakeRelationShip.Entity2Attribute : fakeRelationShip.Entity1Attribute + 49848                     var fromEntityName = isFrom1to2 ? fakeRelationShip.Entity1LogicalName : fakeRelationShip.Entity2Logi + 49849                     var toEntityName = isFrom1to2 ? fakeRelationShip.Entity2LogicalName : fakeRelationShip.Entity1Logica  50  51                    //Check records exist - 48652                    var targetExists = ctx.CreateQuery(fromEntityName) - 48653                                                .Where(e => e.Id == associateRequest.Target.Id) - 48654                                                .FirstOrDefault() != null; + 49852                    var targetExists = ctx.CreateQuery(fromEntityName) + 49853                                                .Where(e => e.Id == associateRequest.Target.Id) + 49854                                                .FirstOrDefault() != null;  55 - 48656                     if (!targetExists) + 49856                     if (!targetExists)  657                    {  658                        throw new Exception(string.Format("{0} with Id {1} doesn't exist", fromEntityName, associateRequ  59                    }  60 - 48061                    var relatedExists = ctx.CreateQuery(toEntityName) - 48062                                                .Where(e => e.Id == relatedEntityReference.Id) - 48063                                                .FirstOrDefault() != null; + 49261                    var relatedExists = ctx.CreateQuery(toEntityName) + 49262                                                .Where(e => e.Id == relatedEntityReference.Id) + 49263                                                .FirstOrDefault() != null;  64 - 48065                     if (!relatedExists) + 49265                     if (!relatedExists)  666                    {  667                        throw new Exception(string.Format("{0} with Id {1} doesn't exist", toEntityName, relatedEntityRe  68                    }  69 - 47470                    var association = new Entity(fakeRelationShip.IntersectEntity) - 47471                    { - 47472                        Attributes = new AttributeCollection - 47473                        { - 47474                            { fromAttribute, associateRequest.Target.Id }, - 47475                            { toAttribute, relatedEntityReference.Id } - 47476                        } - 47477                    }; + 48670                    var association = new Entity(fakeRelationShip.IntersectEntity) + 48671                    { + 48672                        Attributes = new AttributeCollection + 48673                        { + 48674                            { fromAttribute, associateRequest.Target.Id }, + 48675                            { toAttribute, relatedEntityReference.Id } + 48676                        } + 48677                    };  78 - 47479                    service.Create(association); - 47480                } + 48679                    service.Create(association); + 48680                }  81                else  1282                {  83                    //One to many @@ -129,19 +129,19 @@

 1290                    entityToUpdate[fakeRelationShip.Entity2Attribute] = associateRequest.Target;  1291                    service.Update(entityToUpdate);  1292                } - 48693            } + 49893            }  94 - 13895            return new AssociateResponse(); - 13896        } + 15095            return new AssociateResponse(); + 15096        }  97  98        public Type GetResponsibleRequestType() - 400099        { - 4000100            return typeof(AssociateRequest); - 4000101        } + 405099        { + 4050100            return typeof(AssociateRequest); + 4050101        }  102    }  103} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_BulkDeleteRequestExecutor.htm b/test/reports/FakeXrmEasy_BulkDeleteRequestExecutor.htm index f6bc1dc6..6f3ce607 100644 --- a/test/reports/FakeXrmEasy_BulkDeleteRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_BulkDeleteRequestExecutor.htm @@ -105,13 +105,13 @@

 666        }  67  68        public Type GetResponsibleRequestType() - 400069        { - 400070            return typeof(BulkDeleteRequest); - 400071        } + 405069        { + 405070            return typeof(BulkDeleteRequest); + 405071        }  72    }  73} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_CloseIncidentRequestExecutor.htm b/test/reports/FakeXrmEasy_CloseIncidentRequestExecutor.htm index 915416c7..55daf96d 100644 --- a/test/reports/FakeXrmEasy_CloseIncidentRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_CloseIncidentRequestExecutor.htm @@ -108,13 +108,13 @@

 669        }  70  71        public Type GetResponsibleRequestType() - 400072        { - 400073            return typeof(CloseIncidentResponse); - 400074        } + 405072        { + 405073            return typeof(CloseIncidentResponse); + 405074        }  75    }  76} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_CloseQuoteRequestExecutor.htm b/test/reports/FakeXrmEasy_CloseQuoteRequestExecutor.htm index 88bd35f3..ea34f406 100644 --- a/test/reports/FakeXrmEasy_CloseQuoteRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_CloseQuoteRequestExecutor.htm @@ -91,13 +91,13 @@

 652        }  53  54        public Type GetResponsibleRequestType() - 400055        { - 400056            return typeof(CloseQuoteRequest); - 400057        } + 405055        { + 405056            return typeof(CloseQuoteRequest); + 405057        }  58    }  59} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_CreateRequestExecutor.htm b/test/reports/FakeXrmEasy_CreateRequestExecutor.htm index 0dde3932..c1a6e773 100644 --- a/test/reports/FakeXrmEasy_CreateRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_CreateRequestExecutor.htm @@ -65,13 +65,13 @@

 12627        }  28  29        public Type GetResponsibleRequestType() - 400030        { - 400031            return typeof(CreateRequest); - 400032        } + 405030        { + 405031            return typeof(CreateRequest); + 405032        }  33    }  34} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_DateTimeExtensions.htm b/test/reports/FakeXrmEasy_DateTimeExtensions.htm index 7b0ff735..ccfdbbc8 100644 --- a/test/reports/FakeXrmEasy_DateTimeExtensions.htm +++ b/test/reports/FakeXrmEasy_DateTimeExtensions.htm @@ -87,6 +87,6 @@

D:\Git\f  43} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_DefaultEntityInitializerService.htm b/test/reports/FakeXrmEasy_DefaultEntityInitializerService.htm index 6b9fb736..53e44330 100644 --- a/test/reports/FakeXrmEasy_DefaultEntityInitializerService.htm +++ b/test/reports/FakeXrmEasy_DefaultEntityInitializerService.htm @@ -55,55 +55,55 @@

 16  17        public Dictionary<string, IEntityInitializerService> InitializerServiceDictionary;  18 - 400619        public DefaultEntityInitializerService() - 400620        { - 400621            InitializerServiceDictionary = new Dictionary<string, IEntityInitializerService>() - 400622            { - 400623                { InvoiceDetailInitializerService.EntityLogicalName, new InvoiceDetailInitializerService() }, - 400624                { InvoiceInitializerService.EntityLogicalName, new InvoiceInitializerService() } - 400625            }; - 400626        } + 405619        public DefaultEntityInitializerService() + 405620        { + 405621            InitializerServiceDictionary = new Dictionary<string, IEntityInitializerService>() + 405622            { + 405623                { InvoiceDetailInitializerService.EntityLogicalName, new InvoiceDetailInitializerService() }, + 405624                { InvoiceInitializerService.EntityLogicalName, new InvoiceInitializerService() } + 405625            }; + 405626        }  27  28        public Entity Initialize(Entity e, Guid gCallerId, XrmFakedContext ctx, bool isManyToManyRelationshipEntity = fa - 2803429        { + 2814629        {  30            //Validate primary key for dynamic entities - 2803431            var primaryKey = string.Format("{0}id", e.LogicalName); - 2803432             if (!e.Attributes.ContainsKey(primaryKey)) - 2212433            { - 2212434                e[primaryKey] = e.Id; - 2212435            } + 2814631            var primaryKey = string.Format("{0}id", e.LogicalName); + 2814632             if (!e.Attributes.ContainsKey(primaryKey)) + 2221233            { + 2221234                e[primaryKey] = e.Id; + 2221235            }  36 - 2803437             if (isManyToManyRelationshipEntity) - 6038            { - 6039                return e; + 2814637             if (isManyToManyRelationshipEntity) + 7238            { + 7239                return e;  40            }  41 - 2797442            var CallerId = new EntityReference("systemuser", gCallerId); //Create a new instance by default + 2807442            var CallerId = new EntityReference("systemuser", gCallerId); //Create a new instance by default  43 - 2797444            var now = DateTime.UtcNow; + 2807444            var now = DateTime.UtcNow;  45 - 2797446            e.SetValueIfEmpty("createdon", now); + 2807446            e.SetValueIfEmpty("createdon", now);  47  48            //Overriden created on should replace created on - 2797449             if (e.Contains("overriddencreatedon")) + 2807449             if (e.Contains("overriddencreatedon"))  650            {  651                e["createdon"] = e["overriddencreatedon"];  652            }  53 - 2797454            e.SetValueIfEmpty("modifiedon", now); - 2797455            e.SetValueIfEmpty("createdby", CallerId); - 2797456            e.SetValueIfEmpty("modifiedby", CallerId); - 2797457            e.SetValueIfEmpty("ownerid", CallerId); - 2797458            e.SetValueIfEmpty("statecode", new OptionSetValue(0)); //Active by default + 2807454            e.SetValueIfEmpty("modifiedon", now); + 2807455            e.SetValueIfEmpty("createdby", CallerId); + 2807456            e.SetValueIfEmpty("modifiedby", CallerId); + 2807457            e.SetValueIfEmpty("ownerid", CallerId); + 2807458            e.SetValueIfEmpty("statecode", new OptionSetValue(0)); //Active by default  59 - 2797460             if (ctx.InitializationLevel == EntityInitializationLevel.PerEntity) + 2807460             if (ctx.InitializationLevel == EntityInitializationLevel.PerEntity)  36061            {  36062                 if (!string.IsNullOrEmpty(e.LogicalName) && InitializerServiceDictionary.ContainsKey(e.LogicalName))  14463                    InitializerServiceDictionary[e.LogicalName].Initialize(e, gCallerId, ctx, isManyToManyRelationshipEn  36064            }  65 - 2797466            return e; - 2803467        } + 2807466            return e; + 2814667        }  68  69        public Entity Initialize(Entity e, XrmFakedContext ctx, bool isManyToManyRelationshipEntity = false)  070        { @@ -113,6 +113,6 @@

 74} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_DeleteRequestExecutor.htm b/test/reports/FakeXrmEasy_DeleteRequestExecutor.htm index 6bcd2256..943ea48a 100644 --- a/test/reports/FakeXrmEasy_DeleteRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_DeleteRequestExecutor.htm @@ -71,13 +71,13 @@

 932        }  33  34        public Type GetResponsibleRequestType() - 400035        { - 400036            return typeof(DeleteRequest); - 400037        } + 405035        { + 405036            return typeof(DeleteRequest); + 405037        }  38    }  39} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_DisassociateRequestExecutor.htm b/test/reports/FakeXrmEasy_DisassociateRequestExecutor.htm index ff437501..e522e0f4 100644 --- a/test/reports/FakeXrmEasy_DisassociateRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_DisassociateRequestExecutor.htm @@ -106,13 +106,13 @@

 2467        }  68  69        public Type GetResponsibleRequestType() - 400070        { - 400071            return typeof(DisassociateRequest); - 400072        } + 405070        { + 405071            return typeof(DisassociateRequest); + 405072        }  73    }  74} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_EntityExtensions.htm b/test/reports/FakeXrmEasy_EntityExtensions.htm index 85f393c5..1cf76558 100644 --- a/test/reports/FakeXrmEasy_EntityExtensions.htm +++ b/test/reports/FakeXrmEasy_EntityExtensions.htm @@ -88,14 +88,14 @@

D:\Git\fak  15236        }  37  38        public static void ApplyDateBehaviour(this Entity e, XrmFakedContext context) - 1631039        { + 1634839        {  40#if FAKE_XRM_EASY || FAKE_XRM_EASY_2013 - 540041            return; //Do nothing... DateBehavior wasn't available for versions <= 2013 + 541041            return; //Do nothing... DateBehavior wasn't available for versions <= 2013  42#else  43 - 1091044             if (context.DateBehaviour.Count == 0 || e.LogicalName == null || !context.DateBehaviour.ContainsKey(e.Logica - 960045            { - 960046                return; + 1093844             if (context.DateBehaviour.Count == 0 || e.LogicalName == null || !context.DateBehaviour.ContainsKey(e.Logica + 962845            { + 962846                return;  47            }  48  131049            var entityDateBehaviours = context.DateBehaviour[e.LogicalName]; @@ -118,13 +118,13 @@

D:\Git\fak  66                }  15267            }  68#endif - 1631069        } + 1634869        }  70  71        public static void ProjectAttributes(Entity e, Entity projected, LinkEntity le, XrmFakedContext context) - 1374072        { - 1374073             var sAlias = string.IsNullOrWhiteSpace(le.EntityAlias) ? le.LinkToEntityName : le.EntityAlias; + 1377872        { + 1377873             var sAlias = string.IsNullOrWhiteSpace(le.EntityAlias) ? le.LinkToEntityName : le.EntityAlias;  74 - 1374075             if (le.Columns.AllColumns) + 1377875             if (le.Columns.AllColumns)  1276            {  69677                foreach (var attKey in e.Attributes.Keys)  33078                { @@ -143,165 +143,165 @@

D:\Git\fak  091                }  1292            }  93            else - 1372894            { - 4269695                foreach (var attKey in le.Columns.Columns) - 75696                { - 75697                    var linkedAttKey = sAlias + "." + attKey; - 75698                     if (e.Attributes.ContainsKey(linkedAttKey)) - 69699                        projected[linkedAttKey] = e[linkedAttKey]; + 1376694            { + 4284295                foreach (var attKey in le.Columns.Columns) + 77296                { + 77297                    var linkedAttKey = sAlias + "." + attKey; + 77298                     if (e.Attributes.ContainsKey(linkedAttKey)) + 71299                        projected[linkedAttKey] = e[linkedAttKey];  100 - 756101                     if (e.FormattedValues.ContainsKey(linkedAttKey)) + 772101                     if (e.FormattedValues.ContainsKey(linkedAttKey))  12102                        projected.FormattedValues[linkedAttKey] = e.FormattedValues[linkedAttKey]; - 756103                } + 772103                }  104 - 13728105            } + 13766105            }  106 - 41352107            foreach (var nestedLinkedEntity in le.LinkEntities) + 41466107            foreach (var nestedLinkedEntity in le.LinkEntities)  66108            {  66109                ProjectAttributes(e, projected, nestedLinkedEntity, context);  66110            } - 13740111        } + 13778111        }  112  113        public static Entity ProjectAttributes(this Entity e, QueryExpression qe, XrmFakedContext context) - 31026114        { - 31026115             if (qe.ColumnSet == null || qe.ColumnSet.AllColumns) + 31064114        { + 31064115             if (qe.ColumnSet == null || qe.ColumnSet.AllColumns)  1723116            {  1723117                return RemoveNullAttributes(e); //return all the original attributes  118            }  119            else - 29303120            { + 29341120            {  121                //Return selected list of attributes in a projected entity - 29303122                Entity projected = null; + 29341122                Entity projected = null;  123  124                //However, if we are using proxy types, we must create a instance of the appropiate class - 29303125                 if (context.ProxyTypesAssembly != null) - 2249126                { - 2249127                    var subClassType = context.FindReflectedType(e.LogicalName); - 2249128                     if (subClassType != null) - 2249129                    { - 2249130                        var instance = Activator.CreateInstance(subClassType); - 2249131                        projected = (Entity)instance; - 2249132                        projected.Id = e.Id; - 2249133                    } + 29341125                 if (context.ProxyTypesAssembly != null) + 2255126                { + 2255127                    var subClassType = context.FindReflectedType(e.LogicalName); + 2255128                     if (subClassType != null) + 2255129                    { + 2255130                        var instance = Activator.CreateInstance(subClassType); + 2255131                        projected = (Entity)instance; + 2255132                        projected.Id = e.Id; + 2255133                    }  134                    else  0135                        projected = new Entity(e.LogicalName) { Id = e.Id }; //fallback to generic type if type not foun - 2249136                } + 2255136                }  137                else - 27054138                    projected = new Entity(e.LogicalName) { Id = e.Id }; + 27086138                    projected = new Entity(e.LogicalName) { Id = e.Id };  139  140 - 96915141                foreach (var attKey in qe.ColumnSet.Columns) - 4509142                { + 97065141                foreach (var attKey in qe.ColumnSet.Columns) + 4527142                {  143                    //Check if attribute really exists in metadata - 4509144                     if (!context.AttributeExistsInMetadata(e.LogicalName, attKey)) + 4527144                     if (!context.AttributeExistsInMetadata(e.LogicalName, attKey))  12145                    {  12146                        OrganizationServiceFaultQueryBuilderNoAttributeException.Throw(attKey);  0147                    }  148 - 4497149                     if (e.Attributes.ContainsKey(attKey) && e.Attributes[attKey] != null) - 2713150                    { - 2713151                        projected[attKey] = CloneAttribute(e[attKey], context); + 4515149                     if (e.Attributes.ContainsKey(attKey) && e.Attributes[attKey] != null) + 2731150                    { + 2731151                        projected[attKey] = CloneAttribute(e[attKey], context);  152 - 2713153                        string formattedValue = ""; + 2731153                        string formattedValue = "";  154 - 2713155                         if (e.FormattedValues.TryGetValue(attKey, out formattedValue)) + 2731155                         if (e.FormattedValues.TryGetValue(attKey, out formattedValue))  6156                        {  6157                            projected.FormattedValues[attKey] = formattedValue;  6158                        } - 2713159                    } - 4497160                } + 2731159                    } + 4515160                }  161  162  163                //Plus attributes from joins - 115221164                foreach (var le in qe.LinkEntities) - 13674165                { - 13674166                    ProjectAttributes(RemoveNullAttributes(e), projected, le, context); - 13674167                } - 29291168                return RemoveNullAttributes(projected); + 115411164                foreach (var le in qe.LinkEntities) + 13712165                { + 13712166                    ProjectAttributes(RemoveNullAttributes(e), projected, le, context); + 13712167                } + 29329168                return RemoveNullAttributes(projected);  169            } - 31014170        } + 31052170        }  171  172        public static Entity RemoveNullAttributes(Entity entity) - 44688173        { - 44688174            IList<string> nullAttributes = entity.Attributes - 293941175                .Where(attribute => attribute.Value == null || - 293941176                                  (attribute.Value is AliasedValue && (attribute.Value as AliasedValue).Value == null)) - 44851177                .Select(attribute => attribute.Key).ToList(); - 134390178            foreach (var nullAttribute in nullAttributes) - 163179            { - 163180                entity.Attributes.Remove(nullAttribute); - 163181            } - 44688182            return entity; - 44688183        } + 44764173        { + 44764174            IList<string> nullAttributes = entity.Attributes + 294695175                .Where(attribute => attribute.Value == null || + 294695176                                  (attribute.Value is AliasedValue && (attribute.Value as AliasedValue).Value == null)) + 44951177                .Select(attribute => attribute.Key).ToList(); + 134666178            foreach (var nullAttribute in nullAttributes) + 187179            { + 187180                entity.Attributes.Remove(nullAttribute); + 187181            } + 44764182            return entity; + 44764183        }  184  185        public static object CloneAttribute(object attributeValue, XrmFakedContext context = null) - 1975629186        { - 1975629187             if (attributeValue == null) - 552212188                return null; + 1980203186        { + 1980203187             if (attributeValue == null) + 553480188                return null;  189 - 1423417190            var type = attributeValue.GetType(); - 1423417191             if (type == typeof(string)) - 20428192                return new string((attributeValue as string).ToCharArray()); - 1402989193             else if (type == typeof(EntityReference) - 1402989194#if FAKE_XRM_EASY - 1402989195                            || type == typeof(Microsoft.Xrm.Client.CrmEntityReference) - 1402989196#endif - 1402989197                    ) - 552416198            { - 552416199                var original = (attributeValue as EntityReference); - 552416200                var clone = new EntityReference(original.LogicalName, original.Id); + 1426723190            var type = attributeValue.GetType(); + 1426723191             if (type == typeof(string)) + 20642192                return new string((attributeValue as string).ToCharArray()); + 1406081193             else if (type == typeof(EntityReference) + 1406081194#if FAKE_XRM_EASY + 1406081195                            || type == typeof(Microsoft.Xrm.Client.CrmEntityReference) + 1406081196#endif + 1406081197                    ) + 553660198            { + 553660199                var original = (attributeValue as EntityReference); + 553660200                var clone = new EntityReference(original.LogicalName, original.Id);  201 - 552416202                 if (context != null && !string.IsNullOrEmpty(original.LogicalName) && context.EntityMetadata.ContainsKey - 552416203                    context.Data.ContainsKey(original.LogicalName) && context.Data[original.LogicalName].ContainsKey(ori + 553660202                 if (context != null && !string.IsNullOrEmpty(original.LogicalName) && context.EntityMetadata.ContainsKey + 553660203                    context.Data.ContainsKey(original.LogicalName) && context.Data[original.LogicalName].ContainsKey(ori  54204                {  54205                    clone.Name = context.Data[original.LogicalName][original.Id].GetAttributeValue<string>(context.Entit  54206                }  207                else - 552362208                { - 552362209                    clone.Name = CloneAttribute(original.Name) as string; - 552362210                } + 553606208                { + 553606209                    clone.Name = CloneAttribute(original.Name) as string; + 553606210                }  211  212#if !FAKE_XRM_EASY && !FAKE_XRM_EASY_2013 && !FAKE_XRM_EASY_2015 - 276825213                 if (original.KeyAttributes != null) - 276825214                { - 276825215                    clone.KeyAttributes = new KeyAttributeCollection(); - 276837216                    clone.KeyAttributes.AddRange(original.KeyAttributes.Select(kvp => new KeyValuePair<string, object>(C - 276825217                } + 277503213                 if (original.KeyAttributes != null) + 277503214                { + 277503215                    clone.KeyAttributes = new KeyAttributeCollection(); + 277515216                    clone.KeyAttributes.AddRange(original.KeyAttributes.Select(kvp => new KeyValuePair<string, object>(C + 277503217                }  218#endif - 552416219                return clone; + 553660219                return clone;  220            } - 850573221             else if (type == typeof(BooleanManagedProperty)) + 852421221             else if (type == typeof(BooleanManagedProperty))  18222            {  18223                var original = (attributeValue as BooleanManagedProperty);  18224                return new BooleanManagedProperty(original.Value);  225            } - 850555226             else if (type == typeof(OptionSetValue)) - 168939227            { - 168939228                var original = (attributeValue as OptionSetValue); - 168939229                return new OptionSetValue(original.Value); + 852403226             else if (type == typeof(OptionSetValue)) + 169303227            { + 169303228                var original = (attributeValue as OptionSetValue); + 169303229                return new OptionSetValue(original.Value);  230            } - 681616231             else if (type == typeof(AliasedValue)) - 121368232            { - 121368233                var original = (attributeValue as AliasedValue); - 121368234                return new AliasedValue(original.EntityLogicalName, original.AttributeLogicalName, CloneAttribute(origin + 683100231             else if (type == typeof(AliasedValue)) + 121696232            { + 121696233                var original = (attributeValue as AliasedValue); + 121696234                return new AliasedValue(original.EntityLogicalName, original.AttributeLogicalName, CloneAttribute(origin  235            } - 560248236             else if (type == typeof(Money)) + 561404236             else if (type == typeof(Money))  1125237            {  1125238                var original = (attributeValue as Money);  1125239                return new Money(original.Value);  240            } - 559123241             else if (attributeValue.GetType() == typeof(EntityCollection)) + 560279241             else if (attributeValue.GetType() == typeof(EntityCollection))  12242            {  12243                var collection = attributeValue as EntityCollection;  24244                return new EntityCollection(collection.Entities.Select(e => e.Clone(e.GetType())).ToList());  245            } - 559111246             else if (attributeValue is IEnumerable<Entity>) + 560267246             else if (attributeValue is IEnumerable<Entity>)  6247            {  6248                var enumerable = attributeValue as IEnumerable<Entity>;  18249                return enumerable.Select(e => e.Clone(e.GetType())).ToArray();  250            }  251#if !FAKE_XRM_EASY - 466380252             else if (type == typeof(byte[])) + 467430252             else if (type == typeof(byte[]))  5253            {  5254                var original = (attributeValue as byte[]);  5255                var copy = new byte[original.Length]; @@ -310,64 +310,64 @@

D:\Git\fak  258            }  259#endif  260#if FAKE_XRM_EASY_9 - 94071261             else if (attributeValue is OptionSetValueCollection) + 94281261             else if (attributeValue is OptionSetValueCollection)  292262            {  292263                var original = (attributeValue as OptionSetValueCollection);  292264                var copy = new OptionSetValueCollection(original.ToArray());  292265                return copy;  266            }  267#endif - 558808268             else if (type == typeof(int) || type == typeof(Int64)) + 559964268             else if (type == typeof(int) || type == typeof(Int64))  4773269                return attributeValue; //Not a reference type - 554035270             else if (type == typeof(decimal)) + 555191270             else if (type == typeof(decimal))  327271                return attributeValue; //Not a reference type - 553708272             else if (type == typeof(double)) + 554864272             else if (type == typeof(double))  270273                return attributeValue; //Not a reference type - 553438274             else if (type == typeof(float)) + 554594274             else if (type == typeof(float))  36275                return attributeValue; //Not a reference type - 553402276             else if (type == typeof(byte)) + 554558276             else if (type == typeof(byte))  0277                return attributeValue; //Not a reference type - 553402278             else if (type == typeof(float)) + 554558278             else if (type == typeof(float))  0279                return attributeValue; //Not a reference type - 553402280             else if (type == typeof(bool)) - 44580281                return attributeValue; //Not a reference type - 508822282             else if (type == typeof(Guid)) - 173368283                return attributeValue; //Not a reference type - 335454284             else if (type == typeof(DateTime)) - 335370285                return attributeValue; //Not a reference type + 554558280             else if (type == typeof(bool)) + 44620281                return attributeValue; //Not a reference type + 509938282             else if (type == typeof(Guid)) + 173756283                return attributeValue; //Not a reference type + 336182284             else if (type == typeof(DateTime)) + 336098285                return attributeValue; //Not a reference type  84286             else if (attributeValue is Enum)  84287                return attributeValue; //Not a reference type  288  0289            throw new Exception(string.Format("Attribute type not supported when trying to clone attribute '{0}'", type. - 1975629290        } + 1980203290        }  291  292        public static Entity Clone(this Entity e, XrmFakedContext context = null) - 55920293        { - 55920294            var cloned = new Entity(e.LogicalName); - 55920295            cloned.Id = e.Id; - 55920296            cloned.LogicalName = e.LogicalName; + 56058293        { + 56058294            var cloned = new Entity(e.LogicalName); + 56058295            cloned.Id = e.Id; + 56058296            cloned.LogicalName = e.LogicalName;  297 - 55920298             if (e.FormattedValues != null) - 55920299            { - 55920300                var formattedValues = new FormattedValueCollection(); - 167784301                foreach (var key in e.FormattedValues.Keys) + 56058298             if (e.FormattedValues != null) + 56058299            { + 56058300                var formattedValues = new FormattedValueCollection(); + 168198301                foreach (var key in e.FormattedValues.Keys)  12302                    formattedValues.Add(key, e.FormattedValues[key]);  303 - 55920304                cloned.Inject("FormattedValues", formattedValues); - 55920305            } + 56058304                cloned.Inject("FormattedValues", formattedValues); + 56058305            }  306 - 1043318307            foreach (var attKey in e.Attributes.Keys) - 437779308            { - 437779309                 cloned[attKey] = e[attKey] != null ? CloneAttribute(e[attKey], context) : null; - 437779310            } + 1046024307            foreach (var attKey in e.Attributes.Keys) + 438925308            { + 438925309                 cloned[attKey] = e[attKey] != null ? CloneAttribute(e[attKey], context) : null; + 438925310            }  311#if !FAKE_XRM_EASY && !FAKE_XRM_EASY_2013 && !FAKE_XRM_EASY_2015 - 83952312            foreach (var attKey in e.KeyAttributes.Keys) + 84177312            foreach (var attKey in e.KeyAttributes.Keys)  0313            {  0314                 cloned.KeyAttributes[attKey] = e.KeyAttributes[attKey] != null ? CloneAttribute(e.KeyAttributes[attKey])  0315            }  316#endif - 55920317            return cloned; - 55920318        } + 56058317            return cloned; + 56058318        }  319  320        public static T Clone<T>(this Entity e) where T : Entity  0321        { @@ -375,36 +375,36 @@

D:\Git\fak  0323        }  324  325        public static Entity Clone(this Entity e, Type t, XrmFakedContext context = null) - 97443326        { - 97443327             if (t == null) + 97643326        { + 97643327             if (t == null)  431328                return e.Clone(context);  329 - 97012330            var cloned = Activator.CreateInstance(t) as Entity; - 97012331            cloned.Id = e.Id; - 97012332            cloned.LogicalName = e.LogicalName; + 97212330            var cloned = Activator.CreateInstance(t) as Entity; + 97212331            cloned.Id = e.Id; + 97212332            cloned.LogicalName = e.LogicalName;  333 - 97012334             if (e.FormattedValues != null) - 97012335            { - 97012336                var formattedValues = new FormattedValueCollection(); - 291264337                foreach (var key in e.FormattedValues.Keys) + 97212334             if (e.FormattedValues != null) + 97212335            { + 97212336                var formattedValues = new FormattedValueCollection(); + 291864337                foreach (var key in e.FormattedValues.Keys)  114338                    formattedValues.Add(key, e.FormattedValues[key]);  339 - 97012340                cloned.Inject("FormattedValues", formattedValues); - 97012341            } + 97212340                cloned.Inject("FormattedValues", formattedValues); + 97212341            }  342 - 2016792343            foreach (var attKey in e.Attributes.Keys) - 862878344            { - 862878345                 cloned[attKey] = e[attKey] != null ? CloneAttribute(e[attKey], context) : null; - 862878346            } + 2021212343            foreach (var attKey in e.Attributes.Keys) + 864788344            { + 864788345                 cloned[attKey] = e[attKey] != null ? CloneAttribute(e[attKey], context) : null; + 864788346            }  347  348#if !FAKE_XRM_EASY && !FAKE_XRM_EASY_2013 && !FAKE_XRM_EASY_2015 - 146325349            foreach (var attKey in e.KeyAttributes.Keys) + 146649349            foreach (var attKey in e.KeyAttributes.Keys)  9350            {  9351                 cloned.KeyAttributes[attKey] = e.KeyAttributes[attKey] != null ? CloneAttribute(e.KeyAttributes[attKey])  9352            }  353#endif - 97012354            return cloned; - 97443355        } + 97212354            return cloned; + 97643355        }  356  357        /// <summary>  358        /// Extension method to join the attributes of entity e and otherEntity @@ -414,23 +414,23 @@

D:\Git\fak  362        /// <param name="attributes"></param>  363        /// <returns></returns>  364        public static Entity JoinAttributes(this Entity e, Entity otherEntity, ColumnSet columnSet, string alias, XrmFak - 14981365        { - 15158366             if (otherEntity == null) return e; //Left Join where otherEntity was not matched + 15019365        { + 15196366             if (otherEntity == null) return e; //Left Join where otherEntity was not matched  367 - 14804368            otherEntity = otherEntity.Clone(); //To avoid joining entities from/to the same entities, which would cause  + 14842368            otherEntity = otherEntity.Clone(); //To avoid joining entities from/to the same entities, which would cause   369 - 14804370             if (columnSet.AllColumns) - 14804371            { - 286190372                foreach (var attKey in otherEntity.Attributes.Keys) - 120889373                { - 120889374                    e[alias + "." + attKey] = new AliasedValue(otherEntity.LogicalName, attKey, otherEntity[attKey]); - 120889375                } + 14842370             if (columnSet.AllColumns) + 14842371            { + 286960372                foreach (var attKey in otherEntity.Attributes.Keys) + 121217373                { + 121217374                    e[alias + "." + attKey] = new AliasedValue(otherEntity.LogicalName, attKey, otherEntity[attKey]); + 121217375                }  376 - 44436377                foreach (var attKey in otherEntity.FormattedValues.Keys) + 44550377                foreach (var attKey in otherEntity.FormattedValues.Keys)  12378                {  12379                    e.FormattedValues[alias + "." + attKey] = otherEntity.FormattedValues[attKey];  12380                } - 14804381            } + 14842381            }  382            else  0383            {  384                //Return selected list of attributes @@ -456,8 +456,8 @@

D:\Git\fak  0404                    }  0405                }  0406            } - 14804407            return e; - 14981408        } + 14842407            return e; + 15019408        }  409  410        public static Entity JoinAttributes(this Entity e, IEnumerable<Entity> otherEntities, ColumnSet columnSet, strin  0411        { @@ -513,54 +513,54 @@

D:\Git\fak  461        /// <param name="sAttributeName"></param>  462        /// <returns></returns>  463        public static object KeySelector(this Entity e, string sAttributeName, XrmFakedContext context) - 30001464        { - 30001465             if (sAttributeName.Contains(".")) + 30077464        { + 30077465             if (sAttributeName.Contains("."))  192466            {  467                //Do not lowercase the alias prefix  192468                var splitted = sAttributeName.Split('.');  192469                sAttributeName = string.Format("{0}.{1}", splitted[0], splitted[1].ToLower());  192470            }  471            else - 29809472            { - 29809473                sAttributeName = sAttributeName.ToLower(); - 29809474            } + 29885472            { + 29885473                sAttributeName = sAttributeName.ToLower(); + 29885474            }  475 - 30001476             if (!e.Attributes.ContainsKey(sAttributeName)) - 162477            { + 30077476             if (!e.Attributes.ContainsKey(sAttributeName)) + 174477            {  478                //Check if it is the primary key - 162479                 if (sAttributeName.Contains("id") && - 162480                   e.LogicalName.ToLower().Equals(sAttributeName.Substring(0, sAttributeName.Length - 2))) + 174479                 if (sAttributeName.Contains("id") && + 174480                   e.LogicalName.ToLower().Equals(sAttributeName.Substring(0, sAttributeName.Length - 2)))  0481                {  0482                    return e.Id;  483                } - 162484                return Guid.Empty; //Atrribute is null or doesn´t exists so it can´t be joined + 174484                return Guid.Empty; //Atrribute is null or doesn´t exists so it can´t be joined  485            }  486 - 29839487            object keyValue = null; + 29903487            object keyValue = null;  488            AliasedValue aliasedValue; - 29839489             if ((aliasedValue = e[sAttributeName] as AliasedValue) != null) + 29903489             if ((aliasedValue = e[sAttributeName] as AliasedValue) != null)  192490            {  192491                keyValue = aliasedValue.Value;  192492            }  493            else - 29647494            { - 29647495                keyValue = e[sAttributeName]; - 29647496            } + 29711494            { + 29711495                keyValue = e[sAttributeName]; + 29711496            }  497 - 29839498            EntityReference entityReference = keyValue as EntityReference; - 29839499             if (entityReference != null) - 14462500                return entityReference.Id; + 29903498            EntityReference entityReference = keyValue as EntityReference; + 29903499             if (entityReference != null) + 14494500                return entityReference.Id;  501 - 15377502            OptionSetValue optionSetValue = keyValue as OptionSetValue; - 15377503             if (optionSetValue != null) + 15409502            OptionSetValue optionSetValue = keyValue as OptionSetValue; + 15409503             if (optionSetValue != null)  0504                return optionSetValue.Value;  505 - 15377506            Money money = keyValue as Money; - 15377507             if (money != null) + 15409506            Money money = keyValue as Money; + 15409507             if (money != null)  0508                return money.Value;  509 - 15377510            return keyValue; - 30001511        } + 15409510            return keyValue; + 30077511        }  512  513        /// <summary>  514        /// Extension method to "hack" internal set properties on sealed classes via reflection @@ -569,18 +569,18 @@

D:\Git\fak  517        /// <param name="property"></param>  518        /// <param name="value"></param>  519        public static void Inject(this Entity e, string property, object value) - 152968520        { - 152968521            e.GetType().GetProperty(property).SetValue(e, value, null); - 152968522        } + 153306520        { + 153306521            e.GetType().GetProperty(property).SetValue(e, value, null); + 153306522        }  523  524        public static void SetValueIfEmpty(this Entity e, string property, object value) - 167862525        { - 167862526            var containsKey = e.Attributes.ContainsKey(property); - 167862527             if (!containsKey || containsKey && e[property] == null) - 167573528            { - 167573529                e[property] = value; - 167573530            } - 167862531        } + 168462525        { + 168462526            var containsKey = e.Attributes.ContainsKey(property); + 168462527             if (!containsKey || containsKey && e[property] == null) + 168173528            { + 168173529                e[property] = value; + 168173530            } + 168462531        }  532  533        /// <summary>  534        /// ToEntityReference implementation which converts an entity into an entity reference with key attribute info a @@ -601,6 +601,6 @@

D:\Git\fak  549} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_EntityMetadataExtensions.htm b/test/reports/FakeXrmEasy_EntityMetadataExtensions.htm index 5cebdfec..5e2c3022 100644 --- a/test/reports/FakeXrmEasy_EntityMetadataExtensions.htm +++ b/test/reports/FakeXrmEasy_EntityMetadataExtensions.htm @@ -15,10 +15,10 @@

Summary

Class:FakeXrmEasy.Extensions.EntityMetadataExtensions Assembly:FakeXrmEasy File(s):D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\Extensions\EntityMetadataExtensions.cs -Covered lines:23 +Covered lines:29 Uncovered lines:0 -Coverable lines:23 -Total lines:47 +Coverable lines:29 +Total lines:57 Line coverage:100% Branch coverage:100% @@ -32,6 +32,8 @@

Metrics

SetAttributeCollection(...)1100100 SetSealedPropertyValue(...)1100100 SetSealedPropertyValue(...)1100100 +SetSealedPropertyValue(...)1100100 +SetSealedPropertyValue(...)1100100

File(s)

@@ -50,11 +52,11 @@

D:  9    public static class EntityMetadataExtensions  10    {  11        public static void SetAttributeCollection(this EntityMetadata entityMetadata, AttributeMetadata[] attributes) - 612        { + 2412        {  13            //AttributeMetadata is internal set in a sealed class so... just doing this  14 - 615            entityMetadata.GetType().GetProperty("Attributes").SetValue(entityMetadata, attributes, null); - 616        } + 2415            entityMetadata.GetType().GetProperty("Attributes").SetValue(entityMetadata, attributes, null); + 2416        }  17  18        public static void SetAttribute(this EntityMetadata entityMetadata, AttributeMetadata attribute)  3819        { @@ -84,10 +86,20 @@

D:  362543        {  362544            attributeMetadata.GetType().GetProperty(sPropertyName).SetValue(attributeMetadata, value, null);  362545        }46    }47}4647        public static void SetSealedPropertyValue(this ManyToManyRelationshipMetadata manyToManyRelationshipMetadata, st + 648        { + 649            manyToManyRelationshipMetadata.GetType().GetProperty(sPropertyName).SetValue(manyToManyRelationshipMetadata, + 650        }5152        public static void SetSealedPropertyValue(this OneToManyRelationshipMetadata oneToManyRelationshipMetadata, stri + 653        { + 654            oneToManyRelationshipMetadata.GetType().GetProperty(sPropertyName).SetValue(oneToManyRelationshipMetadata, v + 655        }56    }57} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_EntityReferenceExtensions.htm b/test/reports/FakeXrmEasy_EntityReferenceExtensions.htm index 0c2c5c9a..1ab01b43 100644 --- a/test/reports/FakeXrmEasy_EntityReferenceExtensions.htm +++ b/test/reports/FakeXrmEasy_EntityReferenceExtensions.htm @@ -61,6 +61,6 @@

D  24} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_ExecuteFetchRequestExecutor.htm b/test/reports/FakeXrmEasy_ExecuteFetchRequestExecutor.htm index 6f84268c..3c6e3154 100644 --- a/test/reports/FakeXrmEasy_ExecuteFetchRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_ExecuteFetchRequestExecutor.htm @@ -54,7 +54,7 @@

 12{  13    public class ExecuteFetchRequestExecutor : IFakeMessageExecutor  14    { - 402515        private Dictionary<string, int?> _typeCodes = new Dictionary<string, int?>(); + 407515        private Dictionary<string, int?> _typeCodes = new Dictionary<string, int?>();  16  17        public bool CanExecute(OrganizationRequest request)  4218        { @@ -242,13 +242,13 @@

 343200        }  201  202        public Type GetResponsibleRequestType() - 4000203        { - 4000204            return typeof(ExecuteFetchRequest); - 4000205        } + 4050203        { + 4050204            return typeof(ExecuteFetchRequest); + 4050205        }  206    }  207} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_ExecuteMultipleRequestExecutor.htm b/test/reports/FakeXrmEasy_ExecuteMultipleRequestExecutor.htm index caebbfee..4be0dc36 100644 --- a/test/reports/FakeXrmEasy_ExecuteMultipleRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_ExecuteMultipleRequestExecutor.htm @@ -126,13 +126,13 @@

 4287        }  88  89        public Type GetResponsibleRequestType() - 400090        { - 400091            return typeof(ExecuteMultipleRequest); - 400092        } + 405090        { + 405091            return typeof(ExecuteMultipleRequest); + 405092        }  93    }  94} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_ExecuteTransactionExecutor.htm b/test/reports/FakeXrmEasy_ExecuteTransactionExecutor.htm index 44ba724f..0986f994 100644 --- a/test/reports/FakeXrmEasy_ExecuteTransactionExecutor.htm +++ b/test/reports/FakeXrmEasy_ExecuteTransactionExecutor.htm @@ -72,14 +72,14 @@

 633        }  34  35        public Type GetResponsibleRequestType() - 205436        { - 205437            return typeof(ExecuteTransactionRequest); - 205438        } + 208136        { + 208137            return typeof(ExecuteTransactionRequest); + 208138        }  39    }  40}  41#endif - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_GrantAccessRequestExecutor.htm b/test/reports/FakeXrmEasy_GrantAccessRequestExecutor.htm index fb203e63..0044f12d 100644 --- a/test/reports/FakeXrmEasy_GrantAccessRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_GrantAccessRequestExecutor.htm @@ -57,13 +57,13 @@

 10819        }  20  21        public Type GetResponsibleRequestType() - 400022        { - 400023            return typeof(GrantAccessRequest); - 400024        } + 405022        { + 405023            return typeof(GrantAccessRequest); + 405024        }  25    }  26} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_InitializeFromRequestExecutor.htm b/test/reports/FakeXrmEasy_InitializeFromRequestExecutor.htm index 7ec7a62b..2952ef71 100644 --- a/test/reports/FakeXrmEasy_InitializeFromRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_InitializeFromRequestExecutor.htm @@ -54,9 +54,9 @@

 4215        }  16  17        public Type GetResponsibleRequestType() - 400018        { - 400019            return typeof(InitializeFromRequest); - 400020        } + 405018        { + 405019            return typeof(InitializeFromRequest); + 405020        }  21  22        public OrganizationResponse Execute(OrganizationRequest request, XrmFakedContext ctx)  4223        { @@ -144,6 +144,6 @@

 105} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_InsertOptionValueRequestExecutor.htm b/test/reports/FakeXrmEasy_InsertOptionValueRequestExecutor.htm index da5db578..5b21b4bf 100644 --- a/test/reports/FakeXrmEasy_InsertOptionValueRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_InsertOptionValueRequestExecutor.htm @@ -123,13 +123,13 @@

 3084        }  85  86        public Type GetResponsibleRequestType() - 400087        { - 400088            return typeof(InsertOptionValueRequest); - 400089        } + 405087        { + 405088            return typeof(InsertOptionValueRequest); + 405089        }  90    }  91} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_InsertStatusValueRequestExecutor.htm b/test/reports/FakeXrmEasy_InsertStatusValueRequestExecutor.htm index c04ebc2c..605224e8 100644 --- a/test/reports/FakeXrmEasy_InsertStatusValueRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_InsertStatusValueRequestExecutor.htm @@ -127,13 +127,13 @@

 688        }  89  90        public Type GetResponsibleRequestType() - 400091        { - 400092            return typeof(InsertStatusValueRequest); - 400093        } + 405091        { + 405092            return typeof(InsertStatusValueRequest); + 405093        }  94    }  95} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_InvoiceDetailInitializerService.htm b/test/reports/FakeXrmEasy_InvoiceDetailInitializerService.htm index d8bf0fd7..b15f191f 100644 --- a/test/reports/FakeXrmEasy_InvoiceDetailInitializerService.htm +++ b/test/reports/FakeXrmEasy_InvoiceDetailInitializerService.htm @@ -161,6 +161,6 @@

 123} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_InvoiceInitializerService.htm b/test/reports/FakeXrmEasy_InvoiceInitializerService.htm index 692b3189..925b95c8 100644 --- a/test/reports/FakeXrmEasy_InvoiceInitializerService.htm +++ b/test/reports/FakeXrmEasy_InvoiceInitializerService.htm @@ -66,6 +66,6 @@

 28} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_LoseOpportunityRequestExecutor.htm b/test/reports/FakeXrmEasy_LoseOpportunityRequestExecutor.htm index ba986a30..1d57ad77 100644 --- a/test/reports/FakeXrmEasy_LoseOpportunityRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_LoseOpportunityRequestExecutor.htm @@ -88,13 +88,13 @@

 649        }  50  51        public Type GetResponsibleRequestType() - 400052        { - 400053            return typeof(LoseOpportunityRequest); - 400054        } + 405052        { + 405053            return typeof(LoseOpportunityRequest); + 405054        }  55    }  56} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_MetadataGenerator.htm b/test/reports/FakeXrmEasy_MetadataGenerator.htm index f8069c06..81788f23 100644 --- a/test/reports/FakeXrmEasy_MetadataGenerator.htm +++ b/test/reports/FakeXrmEasy_MetadataGenerator.htm @@ -54,10 +54,10 @@

D:\Git\fake  14        public static IEnumerable<EntityMetadata> FromEarlyBoundEntities(Assembly earlyBoundEntitiesAssembly)  1215        {  1216            List<EntityMetadata> entityMetadatas = new List<EntityMetadata>(); - 1693817            foreach (var earlyBoundEntity in earlyBoundEntitiesAssembly.GetTypes()) - 845118            { - 845119                EntityLogicalNameAttribute entityLogicalNameAttribute = GetCustomAttribute<EntityLogicalNameAttribute>(e - 1397320                 if (entityLogicalNameAttribute == null) continue; + 1698617            foreach (var earlyBoundEntity in earlyBoundEntitiesAssembly.GetTypes()) + 847518            { + 847519                EntityLogicalNameAttribute entityLogicalNameAttribute = GetCustomAttribute<EntityLogicalNameAttribute>(e + 1402120                 if (entityLogicalNameAttribute == null) continue;  292921                EntityMetadata metadata = new EntityMetadata();  292922                metadata.LogicalName = entityLogicalNameAttribute.LogicalName;  23 @@ -165,9 +165,9 @@

D:\Git\fake  12125        }  126  127        private static T GetCustomAttribute<T>(MemberInfo member) where T : Attribute - 740496128        { - 740496129            return (T)Attribute.GetCustomAttribute(member, typeof(T)); - 740496130        } + 740520128        { + 740520129            return (T)Attribute.GetCustomAttribute(member, typeof(T)); + 740520130        }  131  132        private static AttributeMetadata CreateAttributeMetadata(Type propertyType)  78043133        { @@ -293,6 +293,6 @@

D:\Git\fake  253} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_ModifyAccessRequestExecutor.htm b/test/reports/FakeXrmEasy_ModifyAccessRequestExecutor.htm index da975149..859094c0 100644 --- a/test/reports/FakeXrmEasy_ModifyAccessRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_ModifyAccessRequestExecutor.htm @@ -57,13 +57,13 @@

 1219        }  20  21        public Type GetResponsibleRequestType() - 400022        { - 400023            return typeof(ModifyAccessRequest); - 400024        } + 405022        { + 405023            return typeof(ModifyAccessRequest); + 405024        }  25    }  26} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_NavigateToNextEntityOrganizationRequestExecutor.htm b/test/reports/FakeXrmEasy_NavigateToNextEntityOrganizationRequestExecutor.htm index 387a559d..01baa8ba 100644 --- a/test/reports/FakeXrmEasy_NavigateToNextEntityOrganizationRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_NavigateToNextEntityOrganizationRequestExecutor.htm @@ -148,13 +148,13 @@

 6108        }  109  110        public Type GetResponsibleRequestType() - 4000111        { - 4000112            return typeof(OrganizationRequest); - 4000113        } + 4050111        { + 4050112            return typeof(OrganizationRequest); + 4050113        }  114    }  115} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_ObjectExtensions.htm b/test/reports/FakeXrmEasy_ObjectExtensions.htm index 41f1c2f8..581066d0 100644 --- a/test/reports/FakeXrmEasy_ObjectExtensions.htm +++ b/test/reports/FakeXrmEasy_ObjectExtensions.htm @@ -60,10 +60,10 @@

D:\Git\fak  614        private static readonly MethodInfo CloneMethod = typeof(Object).GetMethod("MemberwiseClone", BindingFlags.NonPub  15  16        public static bool IsPrimitive(this Type type) - 1190810617        { - 1448110718             if (type == typeof(String)) return true; - 933510519            return (type.IsValueType & type.IsPrimitive); - 1190810620        } + 893089717        { + 1083991818             if (type == typeof(String)) return true; + 702187619            return (type.IsValueType & type.IsPrimitive); + 893089720        }  21  22        private static FieldInfo GetFieldInfo(Type type, string fieldName)  17201823        { @@ -104,58 +104,58 @@

D:\Git\fak  58  59  60        public static Object Copy(this Object originalObject) - 773161        { - 773162            return InternalCopy(originalObject, new Dictionary<Object, Object>(new ReferenceEqualityComparer())); - 773163        } + 631361        { + 631362            return InternalCopy(originalObject, new Dictionary<Object, Object>(new ReferenceEqualityComparer())); + 631363        }  64  65        private static Object InternalCopy(Object originalObject, IDictionary<Object, Object> visited) - 833154066        { - 1586294467             if (originalObject == null) return null; - 80013668            var typeToReflect = originalObject.GetType(); - 80736869             if (IsPrimitive(typeToReflect)) return originalObject; - 90555670             if (visited.ContainsKey(originalObject)) return visited[originalObject]; - 68025271             if (typeof(Delegate).IsAssignableFrom(typeToReflect)) return null; - 68025272            var cloneObject = CloneMethod.Invoke(originalObject, null); - 68025273             if (typeToReflect.IsArray) - 2358174            { - 2358175                var arrayType = typeToReflect.GetElementType(); - 2358176                 if (IsPrimitive(arrayType) == false) - 2210277                { - 2210278                    Array clonedArray = (Array)cloneObject; - 33213079                    clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), v - 2210280                } - 2358181            } - 68025282            visited.Add(originalObject, cloneObject); - 68025283            CopyFields(originalObject, visited, cloneObject, typeToReflect); - 68025284            RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect); - 68025285            return cloneObject; - 833154086        } + 624702766        { + 1188007867             if (originalObject == null) return null; + 61397668            var typeToReflect = originalObject.GetType(); + 61977269             if (IsPrimitive(typeToReflect)) return originalObject; + 69146870             if (visited.ContainsKey(originalObject)) return visited[originalObject]; + 52489271             if (typeof(Delegate).IsAssignableFrom(typeToReflect)) return null; + 52489272            var cloneObject = CloneMethod.Invoke(originalObject, null); + 52489273             if (typeToReflect.IsArray) + 1953774            { + 1953775                var arrayType = typeToReflect.GetElementType(); + 1953776                 if (IsPrimitive(arrayType) == false) + 1803477                { + 1803478                    Array clonedArray = (Array)cloneObject; + 25789879                    clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), v + 1803480                } + 1953781            } + 52489282            visited.Add(originalObject, cloneObject); + 52489283            CopyFields(originalObject, visited, cloneObject, typeToReflect); + 52489284            RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect); + 52489285            return cloneObject; + 624702786        }  87  88        private static void RecursiveCopyBaseTypePrivateFields(object originalObject, IDictionary<object, object> visite - 261927889        { - 261927890             if (typeToReflect.BaseType != null) - 193902691            { - 193902692                RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType); - 1016387793                CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | Binding - 193902694            } - 261927895        } + 200979289        { + 200979290             if (typeToReflect.BaseType != null) + 148490091            { + 148490092                RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType); + 763019193                CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | Binding + 148490094            } + 200979295        }  96  97        private static void CopyFields(object originalObject, IDictionary<object, object> visited, object cloneObject, T - 261927898        { - 3002661299            foreach (FieldInfo fieldInfo in typeToReflect.GetFields(bindingFlags)) - 11084389100            { - 11084389101                 if (filter != null && filter(fieldInfo) == false) continue; - 14154997102                 if (IsPrimitive(fieldInfo.FieldType)) continue; - 8013781103                var originalFieldValue = fieldInfo.GetValue(originalObject); - 8013781104                var clonedFieldValue = InternalCopy(originalFieldValue, visited); - 8013781105                fieldInfo.SetValue(cloneObject, clonedFieldValue); - 8013781106            } - 2619278107        } + 200979298        { + 2262414499            foreach (FieldInfo fieldInfo in typeToReflect.GetFields(bindingFlags)) + 8297384100            { + 8297384101                 if (filter != null && filter(fieldInfo) == false) continue; + 10593918102                 if (IsPrimitive(fieldInfo.FieldType)) continue; + 6000850103                var originalFieldValue = fieldInfo.GetValue(originalObject); + 6000850104                var clonedFieldValue = InternalCopy(originalFieldValue, visited); + 6000850105                fieldInfo.SetValue(cloneObject, clonedFieldValue); + 6000850106            } + 2009792107        }  108  109        public static T Copy<T>(this T original) - 7731110        { - 7731111            return (T)Copy((Object)original); - 7731112        } + 6313110        { + 6313111            return (T)Copy((Object)original); + 6313112        }  113    }  114  115    public class ReferenceEqualityComparer : EqualityComparer<Object> @@ -218,6 +218,6 @@

D:\Git\fak  172} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_OrganizationServiceFaultInvalidArgument.htm b/test/reports/FakeXrmEasy_OrganizationServiceFaultInvalidArgument.htm index 2be85853..fc1e1133 100644 --- a/test/reports/FakeXrmEasy_OrganizationServiceFaultInvalidArgument.htm +++ b/test/reports/FakeXrmEasy_OrganizationServiceFaultInvalidArgument.htm @@ -57,6 +57,6 @@

 20} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_OrganizationServiceFaultOperatorIsNotValidException.htm b/test/reports/FakeXrmEasy_OrganizationServiceFaultOperatorIsNotValidException.htm index b1ebe624..d1547bf2 100644 --- a/test/reports/FakeXrmEasy_OrganizationServiceFaultOperatorIsNotValidException.htm +++ b/test/reports/FakeXrmEasy_OrganizationServiceFaultOperatorIsNotValidException.htm @@ -57,6 +57,6 @@

 20} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_OrganizationServiceFaultQueryBuilderNoAttributeException.htm b/test/reports/FakeXrmEasy_OrganizationServiceFaultQueryBuilderNoAttributeException.htm index 38cbfa7c..ae0045ac 100644 --- a/test/reports/FakeXrmEasy_OrganizationServiceFaultQueryBuilderNoAttributeException.htm +++ b/test/reports/FakeXrmEasy_OrganizationServiceFaultQueryBuilderNoAttributeException.htm @@ -60,6 +60,6 @@

 22} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_PickFromQueueRequestExecutor.htm b/test/reports/FakeXrmEasy_PickFromQueueRequestExecutor.htm index 0995070b..a9b45810 100644 --- a/test/reports/FakeXrmEasy_PickFromQueueRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_PickFromQueueRequestExecutor.htm @@ -113,15 +113,15 @@

 1074        }  75  76        public Type GetResponsibleRequestType() - 336277        { - 336278            return typeof(PickFromQueueRequest); - 336279        } + 340777        { + 340778            return typeof(PickFromQueueRequest); + 340779        }  80    }  81}  82  83#endif - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_PublishXmlRequestExecutor.htm b/test/reports/FakeXrmEasy_PublishXmlRequestExecutor.htm index 8e71e476..a23dc1aa 100644 --- a/test/reports/FakeXrmEasy_PublishXmlRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_PublishXmlRequestExecutor.htm @@ -64,13 +64,13 @@

 625        }  26  27        public Type GetResponsibleRequestType() - 400028        { - 400029            return typeof(PublishXmlRequest); - 400030        } + 405028        { + 405029            return typeof(PublishXmlRequest); + 405030        }  31    }  32} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_PullRequestException.htm b/test/reports/FakeXrmEasy_PullRequestException.htm index 06b7ef0d..b4eafc6b 100644 --- a/test/reports/FakeXrmEasy_PullRequestException.htm +++ b/test/reports/FakeXrmEasy_PullRequestException.htm @@ -66,6 +66,6 @@

D:\Git\fake-xrm-  27} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_QualifyLeadRequestExecutor.htm b/test/reports/FakeXrmEasy_QualifyLeadRequestExecutor.htm index bf7012f6..87596d2f 100644 --- a/test/reports/FakeXrmEasy_QualifyLeadRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_QualifyLeadRequestExecutor.htm @@ -144,13 +144,13 @@

 30105        }  106  107        public Type GetResponsibleRequestType() - 4000108        { - 4000109            return typeof(QualifyLeadRequest); - 4000110        } + 4050108        { + 4050109            return typeof(QualifyLeadRequest); + 4050110        }  111    }  112} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_QueryExpressionExtensions.htm b/test/reports/FakeXrmEasy_QueryExpressionExtensions.htm index 456bba16..cb8bac16 100644 --- a/test/reports/FakeXrmEasy_QueryExpressionExtensions.htm +++ b/test/reports/FakeXrmEasy_QueryExpressionExtensions.htm @@ -67,13 +67,13 @@

D  29        /// <param name="qe">Query Expression</param>  30        /// <returns></returns>  31        public static QueryExpression Clone(this QueryExpression qe) - 162532        { - 162533            return qe.Copy(); - 162534        } + 165332        { + 165333            return qe.Copy(); + 165334        }  35    }  36} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_ReferenceEqualityComparer.htm b/test/reports/FakeXrmEasy_ReferenceEqualityComparer.htm index 4ed9b753..13d77729 100644 --- a/test/reports/FakeXrmEasy_ReferenceEqualityComparer.htm +++ b/test/reports/FakeXrmEasy_ReferenceEqualityComparer.htm @@ -153,15 +153,15 @@

D:\Git\fak  115    public class ReferenceEqualityComparer : EqualityComparer<Object>  116    {  117        public override bool Equals(object x, object y) - 25104288118        { - 25104288119            return ReferenceEquals(x, y); - 25104288120        } + 18951526118        { + 18951526119            return ReferenceEquals(x, y); + 18951526120        }  121  122        public override int GetHashCode(object obj) - 1578077123        { - 1578077124             if (obj == null) return 0; - 1578077125            return obj.GetHashCode(); - 1578077126        } + 1210047123        { + 1210047124             if (obj == null) return 0; + 1210047125            return obj.GetHashCode(); + 1210047126        }  127    }  128  129    public static class ArrayExtensions @@ -210,6 +210,6 @@

D:\Git\fak  172} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RemoveFromQueueRequestExecutor.htm b/test/reports/FakeXrmEasy_RemoveFromQueueRequestExecutor.htm index d536c7f3..e02a3028 100644 --- a/test/reports/FakeXrmEasy_RemoveFromQueueRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RemoveFromQueueRequestExecutor.htm @@ -70,14 +70,14 @@

 531        }  32  33        public Type GetResponsibleRequestType() - 336234        { - 336235            return typeof(RemoveFromQueueRequest); - 336236        } + 340734        { + 340735            return typeof(RemoveFromQueueRequest); + 340736        }  37    }  38}  39#endif - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RemoveMembersTeamRequestExecutor.htm b/test/reports/FakeXrmEasy_RemoveMembersTeamRequestExecutor.htm index 9135f8c4..ead087c0 100644 --- a/test/reports/FakeXrmEasy_RemoveMembersTeamRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RemoveMembersTeamRequestExecutor.htm @@ -111,13 +111,13 @@

 672        }  73  74        public Type GetResponsibleRequestType() - 400075        { - 400076            return typeof(RemoveMembersTeamRequest); - 400077        } + 405075        { + 405076            return typeof(RemoveMembersTeamRequest); + 405077        }  78    }  79} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RemoveUserFromRecordTeamRequestExecutor.htm b/test/reports/FakeXrmEasy_RemoveUserFromRecordTeamRequestExecutor.htm index 8730ba6b..217fe53c 100644 --- a/test/reports/FakeXrmEasy_RemoveUserFromRecordTeamRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RemoveUserFromRecordTeamRequestExecutor.htm @@ -113,14 +113,14 @@

 574        }  75  76        public Type GetResponsibleRequestType() - 336277        { - 336278            return typeof(RemoveUserFromRecordTeamRequestExecutor); - 336279        } + 340777        { + 340778            return typeof(RemoveUserFromRecordTeamRequestExecutor); + 340779        }  80    }  81}  82#endif - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RetrieveAttributeRequestExecutor.htm b/test/reports/FakeXrmEasy_RetrieveAttributeRequestExecutor.htm index 3f5a9743..3f032ea3 100644 --- a/test/reports/FakeXrmEasy_RetrieveAttributeRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RetrieveAttributeRequestExecutor.htm @@ -96,13 +96,13 @@

 3057        }  58  59        public Type GetResponsibleRequestType() - 400060        { - 400061            return typeof(RetrieveAttributeRequest); - 400062        } + 405060        { + 405061            return typeof(RetrieveAttributeRequest); + 405062        }  63    }  64} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RetrieveEntityRequestExecutor.htm b/test/reports/FakeXrmEasy_RetrieveEntityRequestExecutor.htm index 0946dec5..669a3bae 100644 --- a/test/reports/FakeXrmEasy_RetrieveEntityRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RetrieveEntityRequestExecutor.htm @@ -107,13 +107,13 @@

 1267        }  68  69        public Type GetResponsibleRequestType() - 400070        { - 400071            return typeof(RetrieveEntityRequest); - 400072        } + 405070        { + 405071            return typeof(RetrieveEntityRequest); + 405072        }  73    }  74} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RetrieveExchangeRateRequestExecutor.htm b/test/reports/FakeXrmEasy_RetrieveExchangeRateRequestExecutor.htm index a068e402..9c4a2696 100644 --- a/test/reports/FakeXrmEasy_RetrieveExchangeRateRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RetrieveExchangeRateRequestExecutor.htm @@ -96,13 +96,13 @@

 057        }  58  59        public Type GetResponsibleRequestType() - 400060        { - 400061            return typeof(RetrieveExchangeRateRequest); - 400062        } + 405060        { + 405061            return typeof(RetrieveExchangeRateRequest); + 405062        }  63    }  64} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RetrieveMultipleRequestExecutor.htm b/test/reports/FakeXrmEasy_RetrieveMultipleRequestExecutor.htm index 916304e7..ceb77b81 100644 --- a/test/reports/FakeXrmEasy_RetrieveMultipleRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RetrieveMultipleRequestExecutor.htm @@ -59,37 +59,37 @@

 72917        }  18  19        public OrganizationResponse Execute(OrganizationRequest req, XrmFakedContext ctx) - 223120        { - 223121            var request = req as RetrieveMultipleRequest; - 223122            List<Entity> list = null; - 223123            PagingInfo pageInfo = null; + 226920        { + 226921            var request = req as RetrieveMultipleRequest; + 226922            List<Entity> list = null; + 226923            PagingInfo pageInfo = null;  24            QueryExpression qe;  25 - 223126            string entityName = null; + 226926            string entityName = null;  27 - 223128             if (request.Query is QueryExpression) - 154729            { - 154730                qe = (request.Query as QueryExpression).Clone(); - 154731                entityName = qe.EntityName; + 226928             if (request.Query is QueryExpression) + 157529            { + 157530                qe = (request.Query as QueryExpression).Clone(); + 157531                entityName = qe.EntityName;  32 - 154733                var linqQuery = XrmFakedContext.TranslateQueryExpressionToLinq(ctx, qe); - 153234                list = linqQuery.ToList(); - 153235            } - 68436             else if (request.Query is FetchExpression) - 56537            { - 56538                var fetchXml = (request.Query as FetchExpression).Query; - 56539                var xmlDoc = XrmFakedContext.ParseFetchXml(fetchXml); - 56540                qe = XrmFakedContext.TranslateFetchXmlDocumentToQueryExpression(ctx, xmlDoc); - 54741                entityName = qe.EntityName; + 157533                var linqQuery = XrmFakedContext.TranslateQueryExpressionToLinq(ctx, qe); + 156034                list = linqQuery.ToList(); + 156035            } + 69436             else if (request.Query is FetchExpression) + 57537            { + 57538                var fetchXml = (request.Query as FetchExpression).Query; + 57539                var xmlDoc = XrmFakedContext.ParseFetchXml(fetchXml); + 57540                qe = XrmFakedContext.TranslateFetchXmlDocumentToQueryExpression(ctx, xmlDoc); + 55741                entityName = qe.EntityName;  42 - 54743                var linqQuery = XrmFakedContext.TranslateQueryExpressionToLinq(ctx, qe); - 53544                list = linqQuery.ToList(); + 55743                var linqQuery = XrmFakedContext.TranslateQueryExpressionToLinq(ctx, qe); + 54544                list = linqQuery.ToList();  45 - 53546                 if (xmlDoc.IsAggregateFetchXml()) + 54546                 if (xmlDoc.IsAggregateFetchXml())  14447                {  14448                    list = XrmFakedContext.ProcessAggregateFetchXml(ctx, xmlDoc, list);  14449                } - 53550            } + 54550            }  11951             else if (request.Query is QueryByAttribute)  11952            {  53                // We instantiate a QueryExpression to be executed as we have the implementation done already @@ -120,124 +120,124 @@

 078                throw PullRequestException.NotImplementedOrganizationRequest(request.Query.GetType());  79            }  80 - 218681             if (qe.Distinct) + 222481             if (qe.Distinct)  1882            {  1883                list = GetDistinctEntities(list);  1884            }  85  86            // Handle the top count before taking paging into account - 218687             if (qe.TopCount != null && qe.TopCount.Value < list.Count) + 222487             if (qe.TopCount != null && qe.TopCount.Value < list.Count)  688            {  689                list = list.Take(qe.TopCount.Value).ToList();  690            }  91  92            // Handle TotalRecordCount here? - 218693            int totalRecordCount = -1; - 218694             if (qe?.PageInfo?.ReturnTotalRecordCount == true) + 222493            int totalRecordCount = -1; + 222494             if (qe?.PageInfo?.ReturnTotalRecordCount == true)  2495            {  2496                totalRecordCount = list.Count;  2497            }  98  99            // Handle paging - 2186100            var pageSize = ctx.MaxRetrieveCount; - 2186101            pageInfo = qe.PageInfo; - 2186102            int pageNumber = 1; - 2186103             if (pageInfo != null && pageInfo.PageNumber > 0) - 1197104            { - 1197105                pageNumber = pageInfo.PageNumber; - 1197106                 pageSize = pageInfo.Count == 0 ? ctx.MaxRetrieveCount : pageInfo.Count; - 1197107            } + 2224100            var pageSize = ctx.MaxRetrieveCount; + 2224101            pageInfo = qe.PageInfo; + 2224102            int pageNumber = 1; + 2224103             if (pageInfo != null && pageInfo.PageNumber > 0) + 1207104            { + 1207105                pageNumber = pageInfo.PageNumber; + 1207106                 pageSize = pageInfo.Count == 0 ? ctx.MaxRetrieveCount : pageInfo.Count; + 1207107            }  108  109            // Figure out where in the list we need to start and how many items we need to grab - 2186110            int numberToGet = pageSize; - 2186111            int startPosition = 0; + 2224110            int numberToGet = pageSize; + 2224111            int startPosition = 0;  112 - 2186113             if (pageNumber != 1) + 2224113             if (pageNumber != 1)  36114            {  36115                startPosition = (pageNumber - 1) * pageSize;  36116            }  117 - 2186118             if (list.Count < pageSize) - 1982119            { - 1982120                numberToGet = list.Count; - 1982121            } + 2224118             if (list.Count < pageSize) + 2020119            { + 2020120                numberToGet = list.Count; + 2020121            }  204122             else if (list.Count - pageSize * (pageNumber - 1) < pageSize)  18123            {  18124                numberToGet = list.Count - (pageSize * (pageNumber - 1));  18125            }  126 - 2186127            var recordsToReturn = startPosition + numberToGet > list.Count ? new List<Entity>() : list.GetRange(startPos + 2224127            var recordsToReturn = startPosition + numberToGet > list.Count ? new List<Entity>() : list.GetRange(startPos  128 - 17793129            recordsToReturn.ForEach(e => e.ApplyDateBehaviour(ctx)); - 17793130            recordsToReturn.ForEach(e => PopulateFormattedValues(e)); + 17869129            recordsToReturn.ForEach(e => e.ApplyDateBehaviour(ctx)); + 17869130            recordsToReturn.ForEach(e => PopulateFormattedValues(e));  131 - 2186132            var response = new RetrieveMultipleResponse - 2186133            { - 2186134                Results = new ParameterCollection - 2186135                                 { - 2186136                                    { "EntityCollection", new EntityCollection(recordsToReturn) } - 2186137                                 } - 2186138            }; - 2186139            response.EntityCollection.EntityName = entityName; - 2186140            response.EntityCollection.MoreRecords = (list.Count - pageSize * pageNumber) > 0; - 2186141            response.EntityCollection.TotalRecordCount = totalRecordCount; + 2224132            var response = new RetrieveMultipleResponse + 2224133            { + 2224134                Results = new ParameterCollection + 2224135                                 { + 2224136                                    { "EntityCollection", new EntityCollection(recordsToReturn) } + 2224137                                 } + 2224138            }; + 2224139            response.EntityCollection.EntityName = entityName; + 2224140            response.EntityCollection.MoreRecords = (list.Count - pageSize * pageNumber) > 0; + 2224141            response.EntityCollection.TotalRecordCount = totalRecordCount;  142 - 2186143             if (response.EntityCollection.MoreRecords) + 2224143             if (response.EntityCollection.MoreRecords)  66144            {  66145                var first = response.EntityCollection.Entities.First();  66146                var last = response.EntityCollection.Entities.Last();  66147                response.EntityCollection.PagingCookie = $"<cookie page=\"{pageNumber}\"><{first.LogicalName}id last=\"{  66148            }  149 - 2186150            return response; - 2186151        } + 2224150            return response; + 2224151        }  152  153        /// <summary>  154        /// Populates the formmated values property of this entity record based on the proxy types  155        /// </summary>  156        /// <param name="e"></param>  157        protected void PopulateFormattedValues(Entity e) - 15607158        { + 15645158        {  159            // Iterate through attributes and retrieve formatted values based on type - 79899160            foreach (var attKey in e.Attributes.Keys) - 16539161            { - 16539162                var value = e[attKey]; - 16539163                string formattedValue = ""; - 16539164                 if (!e.FormattedValues.ContainsKey(attKey) && (value != null)) - 16521165                { + 80093160            foreach (var attKey in e.Attributes.Keys) + 16579161            { + 16579162                var value = e[attKey]; + 16579163                string formattedValue = ""; + 16579164                 if (!e.FormattedValues.ContainsKey(attKey) && (value != null)) + 16561165                {  166                    bool bShouldAdd; - 16521167                    formattedValue = this.GetFormattedValueForValue(value, out bShouldAdd); - 16521168                     if (bShouldAdd) + 16561167                    formattedValue = this.GetFormattedValueForValue(value, out bShouldAdd); + 16561168                     if (bShouldAdd)  6169                    {  6170                        e.FormattedValues.Add(attKey, formattedValue);  6171                    } - 16521172                } - 16539173            } - 15607174        } + 16561172                } + 16579173            } + 15645174        }  175  176        protected string GetFormattedValueForValue(object value, out bool bShouldAddFormattedValue) - 20601177        { - 20601178            bShouldAddFormattedValue = false; - 20601179            var sFormattedValue = string.Empty; + 20657177        { + 20657178            bShouldAddFormattedValue = false; + 20657179            var sFormattedValue = string.Empty;  180 - 20601181             if (value is Enum) + 20657181             if (value is Enum)  6182            {  183                // Retrieve the enum type  6184                sFormattedValue = Enum.GetName(value.GetType(), value);  6185                bShouldAddFormattedValue = true;  6186            } - 20595187             else if (value is AliasedValue) - 4080188            { - 4080189                 return this.GetFormattedValueForValue((value as AliasedValue)?.Value, out bShouldAddFormattedValue); + 20651187             else if (value is AliasedValue) + 4096188            { + 4096189                 return this.GetFormattedValueForValue((value as AliasedValue)?.Value, out bShouldAddFormattedValue);  190            }  191 - 16521192            return sFormattedValue; - 20601193        } + 16561192            return sFormattedValue; + 20657193        }  194  195        public Type GetResponsibleRequestType() - 4000196        { - 4000197            return typeof(RetrieveMultipleRequest); - 4000198        } + 4050196        { + 4050197            return typeof(RetrieveMultipleRequest); + 4050198        }  199  200        private static List<Entity> GetDistinctEntities(IEnumerable<Entity> input)  18201        { @@ -257,6 +257,6 @@

 215} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RetrieveOptionSetRequestExecutor.htm b/test/reports/FakeXrmEasy_RetrieveOptionSetRequestExecutor.htm index eb9fe6a6..862041f1 100644 --- a/test/reports/FakeXrmEasy_RetrieveOptionSetRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RetrieveOptionSetRequestExecutor.htm @@ -81,13 +81,13 @@

 642        }  43  44        public Type GetResponsibleRequestType() - 400045        { - 400046            return typeof(RetrieveOptionSetRequest); - 400047        } + 405045        { + 405046            return typeof(RetrieveOptionSetRequest); + 405047        }  48    }  49} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RetrievePrincipalAccessRequestExecutor.htm b/test/reports/FakeXrmEasy_RetrievePrincipalAccessRequestExecutor.htm index f007721c..289eb9a9 100644 --- a/test/reports/FakeXrmEasy_RetrievePrincipalAccessRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RetrievePrincipalAccessRequestExecutor.htm @@ -56,13 +56,13 @@

 9618        }  19  20        public Type GetResponsibleRequestType() - 400021        { - 400022            return typeof(RetrievePrincipalAccessRequest); - 400023        } + 405021        { + 405022            return typeof(RetrievePrincipalAccessRequest); + 405023        }  24    }  25} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RetrieveRelationshipRequestExecutor.htm b/test/reports/FakeXrmEasy_RetrieveRelationshipRequestExecutor.htm index cb9d6735..d0d905cb 100644 --- a/test/reports/FakeXrmEasy_RetrieveRelationshipRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RetrieveRelationshipRequestExecutor.htm @@ -104,13 +104,13 @@

 1864        }  65  66        public Type GetResponsibleRequestType() - 400067        { - 400068            return typeof(RetrieveRelationshipRequest); - 400069        } + 405067        { + 405068            return typeof(RetrieveRelationshipRequest); + 405069        }  70    }  71} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RetrieveRequestExecutor.htm b/test/reports/FakeXrmEasy_RetrieveRequestExecutor.htm index a638ed55..94b569ce 100644 --- a/test/reports/FakeXrmEasy_RetrieveRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RetrieveRequestExecutor.htm @@ -201,13 +201,13 @@

 691162        }  163  164        public Type GetResponsibleRequestType() - 4096165        { - 4096166            return typeof(RetrieveRequest); - 4096167        } + 4146165        { + 4146166            return typeof(RetrieveRequest); + 4146167        }  168    }  169} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RetrieveSharedPrincipalsAndAccessRequestExecutor.htm b/test/reports/FakeXrmEasy_RetrieveSharedPrincipalsAndAccessRequestExecutor.htm index 1ac9aac6..92e491f3 100644 --- a/test/reports/FakeXrmEasy_RetrieveSharedPrincipalsAndAccessRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RetrieveSharedPrincipalsAndAccessRequestExecutor.htm @@ -56,13 +56,13 @@

 3618        }  19  20        public Type GetResponsibleRequestType() - 400021        { - 400022            return typeof(RetrieveSharedPrincipalsAndAccessRequest); - 400023        } + 405021        { + 405022            return typeof(RetrieveSharedPrincipalsAndAccessRequest); + 405023        }  24    }  25} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RetrieveVersionRequestExecutor.htm b/test/reports/FakeXrmEasy_RetrieveVersionRequestExecutor.htm index d26e9a37..6098246c 100644 --- a/test/reports/FakeXrmEasy_RetrieveVersionRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RetrieveVersionRequestExecutor.htm @@ -67,13 +67,13 @@

 629        }  30  31        public Type GetResponsibleRequestType() - 400032        { - 400033            return typeof(RetrieveVersionRequest); - 400034        } + 405032        { + 405033            return typeof(RetrieveVersionRequest); + 405034        }  35    }  36} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_ReviseQuoteRequestExecutor.htm b/test/reports/FakeXrmEasy_ReviseQuoteRequestExecutor.htm index 5754ce22..d97b49f9 100644 --- a/test/reports/FakeXrmEasy_ReviseQuoteRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_ReviseQuoteRequestExecutor.htm @@ -146,13 +146,13 @@

 6107        }  108  109        public Type GetResponsibleRequestType() - 4000110        { - 4000111            return typeof(ReviseQuoteRequest); - 4000112        } + 4050110        { + 4050111            return typeof(ReviseQuoteRequest); + 4050112        }  113    }  114} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_RevokeAccessRequestExecutor.htm b/test/reports/FakeXrmEasy_RevokeAccessRequestExecutor.htm index b665a6ca..96dc7816 100644 --- a/test/reports/FakeXrmEasy_RevokeAccessRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_RevokeAccessRequestExecutor.htm @@ -57,13 +57,13 @@

 1219        }  20  21        public Type GetResponsibleRequestType() - 400022        { - 400023            return typeof(RevokeAccessRequest); - 400024        } + 405022        { + 405023            return typeof(RevokeAccessRequest); + 405024        }  25    }  26} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_SendEmailRequestExecutor.htm b/test/reports/FakeXrmEasy_SendEmailRequestExecutor.htm index f2505138..7a1509bf 100644 --- a/test/reports/FakeXrmEasy_SendEmailRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_SendEmailRequestExecutor.htm @@ -65,13 +65,13 @@

 627        }  28  29        public Type GetResponsibleRequestType() - 400030        { - 400031            return typeof(SendEmailRequest); - 400032        } + 405030        { + 405031            return typeof(SendEmailRequest); + 405032        }  33    }  34} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_SetStateRequestExecutor.htm b/test/reports/FakeXrmEasy_SetStateRequestExecutor.htm index 73250777..ba5659fe 100644 --- a/test/reports/FakeXrmEasy_SetStateRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_SetStateRequestExecutor.htm @@ -69,13 +69,13 @@

 1231        }  32  33        public Type GetResponsibleRequestType() - 400034        { - 400035            return typeof(SetStateRequest); - 400036        } + 405034        { + 405035            return typeof(SetStateRequest); + 405036        }  37    }  38} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_TypeExtensions.htm b/test/reports/FakeXrmEasy_TypeExtensions.htm index f674e505..8ff57c56 100644 --- a/test/reports/FakeXrmEasy_TypeExtensions.htm +++ b/test/reports/FakeXrmEasy_TypeExtensions.htm @@ -48,12 +48,12 @@

D:\Git\fake-  8    public static class TypeExtensions  9    {  10        public static bool IsOptionSet(this Type t) - 619011        { - 619012            var nullableType = Nullable.GetUnderlyingType(t); - 619013             return t == typeof(OptionSetValue) - 619014                   || t.IsEnum - 619015                   || nullableType != null && nullableType.IsEnum; - 619016        } + 621411        { + 621412            var nullableType = Nullable.GetUnderlyingType(t); + 621413             return t == typeof(OptionSetValue) + 621414                   || t.IsEnum + 621415                   || nullableType != null && nullableType.IsEnum; + 621416        }  17  18#if FAKE_XRM_EASY_9  19        public static bool IsOptionSetValueCollection(this Type t) @@ -81,6 +81,6 @@

D:\Git\fake-  41} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_TypedConditionExpression.htm b/test/reports/FakeXrmEasy_TypedConditionExpression.htm index 46bdec7b..b97fec16 100644 --- a/test/reports/FakeXrmEasy_TypedConditionExpression.htm +++ b/test/reports/FakeXrmEasy_TypedConditionExpression.htm @@ -44,23 +44,23 @@

D:\Git  8    /// </summary>  9    public class TypedConditionExpression  10    { - 2488311        public ConditionExpression CondExpression { get; set; } - 1130012        public Type AttributeType { get; set; } + 2546311        public ConditionExpression CondExpression { get; set; } + 1143012        public Type AttributeType { get; set; }  13  14        /// <summary>  15        /// True if the condition came from a left outer join, in which case should be applied only if not null  16        /// </summary> - 855617        public bool IsOuter { get; set; } + 879617        public bool IsOuter { get; set; }  18 - 289119        public TypedConditionExpression(ConditionExpression c) - 289120        { - 289121            IsOuter = false; - 289122            CondExpression = c; - 289123        } + 297119        public TypedConditionExpression(ConditionExpression c) + 297120        { + 297121            IsOuter = false; + 297122            CondExpression = c; + 297123        }  24    }  25} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_UpdateRequestExecutor.htm b/test/reports/FakeXrmEasy_UpdateRequestExecutor.htm index a52444fc..536c2079 100644 --- a/test/reports/FakeXrmEasy_UpdateRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_UpdateRequestExecutor.htm @@ -62,13 +62,13 @@

 1824        }  25  26        public Type GetResponsibleRequestType() - 400027        { - 400028            return typeof(UpdateRequest); - 400029        } + 405027        { + 405028            return typeof(UpdateRequest); + 405029        }  30    }  31} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_UpsertRequestExecutor.htm b/test/reports/FakeXrmEasy_UpsertRequestExecutor.htm index 1c3ea747..ddd3f454 100644 --- a/test/reports/FakeXrmEasy_UpsertRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_UpsertRequestExecutor.htm @@ -82,14 +82,14 @@

 1243        }  44  45        public Type GetResponsibleRequestType() - 205446        { - 205447            return typeof(UpsertRequest); - 205448        } + 208146        { + 208147            return typeof(UpsertRequest); + 208148        }  49    }  50}  51#endif - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_WhoAmIRequestExecutor.htm b/test/reports/FakeXrmEasy_WhoAmIRequestExecutor.htm index 7fca70eb..3cb40392 100644 --- a/test/reports/FakeXrmEasy_WhoAmIRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_WhoAmIRequestExecutor.htm @@ -62,13 +62,13 @@

 624        }  25  26        public Type GetResponsibleRequestType() - 400027        { - 400028            return typeof(WhoAmIRequest); - 400029        } + 405027        { + 405028            return typeof(WhoAmIRequest); + 405029        }  30    }  31} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_WinOpportunityRequestExecutor.htm b/test/reports/FakeXrmEasy_WinOpportunityRequestExecutor.htm index d1802121..63303f44 100644 --- a/test/reports/FakeXrmEasy_WinOpportunityRequestExecutor.htm +++ b/test/reports/FakeXrmEasy_WinOpportunityRequestExecutor.htm @@ -88,13 +88,13 @@

 649        }  50  51        public Type GetResponsibleRequestType() - 400052        { - 400053            return typeof(WinOpportunityRequest); - 400054        } + 405052        { + 405053            return typeof(WinOpportunityRequest); + 405054        }  55    }  56} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_XmlExtensionsForFetchXml.htm b/test/reports/FakeXrmEasy_XmlExtensionsForFetchXml.htm index 5cb6ceec..69eeb1a6 100644 --- a/test/reports/FakeXrmEasy_XmlExtensionsForFetchXml.htm +++ b/test/reports/FakeXrmEasy_XmlExtensionsForFetchXml.htm @@ -15,12 +15,12 @@

Summary

Class:FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml Assembly:FakeXrmEasy File(s):D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\Extensions\XmlExtensionsForFetchXml.cs -Covered lines:470 -Uncovered lines:31 +Covered lines:472 +Uncovered lines:29 Coverable lines:501 Total lines:801 -Line coverage:93.8% -Branch coverage:63.2% +Line coverage:94.2% +Branch coverage:63.6%

Metrics

@@ -48,7 +48,7 @@

Metrics

ToOrderExpressionList(...)3100100 ToFilterExpression(...)8100100 ToValue(...)1100100 -ToConditionExpression(...)12496.3855.24 +ToConditionExpression(...)12497.8355.94 GetValueBasedOnType(...)3273.2475.61 ValueNeedsConverting(...)1100100 GetConditionExpressionValueCast(...)1192.8685.71 @@ -92,42 +92,42 @@

D:  630        };  31  32        public static bool IsAttributeTrue(this XElement elem, string attributeName) - 209333        { - 209334             var val = elem.GetAttribute(attributeName)?.Value; + 211333        { + 211334             var val = elem.GetAttribute(attributeName)?.Value;  35 - 209336            return "true".Equals(val, StringComparison.InvariantCultureIgnoreCase) - 209337                || "1".Equals(val, StringComparison.InvariantCultureIgnoreCase); - 209338        } + 211336            return "true".Equals(val, StringComparison.InvariantCultureIgnoreCase) + 211337                || "1".Equals(val, StringComparison.InvariantCultureIgnoreCase); + 211338        }  39  40        public static bool IsAggregateFetchXml(this XDocument doc) - 170941        { - 170942            return doc.Root.IsAttributeTrue("aggregate"); - 170943        } + 172941        { + 172942            return doc.Root.IsAttributeTrue("aggregate"); + 172943        }  44  45        public static bool IsFetchXmlNodeValid(this XElement elem) - 627546        { - 627547             switch (elem.Name.LocalName) + 633546        { + 633547             switch (elem.Name.LocalName)  48            {  49                case "filter": - 79650                    return true; + 80650                    return true;  51  52                case "value":  53                case "fetch": - 111454                    return true; + 112454                    return true;  55  56                case "entity": - 102457                    return elem.GetAttribute("name") != null; + 103457                    return elem.GetAttribute("name") != null;  58  59                case "all-attributes":  1860                    return true;  61  62                case "attribute": - 208063                    return elem.GetAttribute("name") != null; + 209063                    return elem.GetAttribute("name") != null;  64  65                case "link-entity": - 17266                    return elem.GetAttribute("name") != null - 17267                            && elem.GetAttribute("from") != null - 17268                            && elem.GetAttribute("to") != null; + 18266                    return elem.GetAttribute("name") != null + 18267                            && elem.GetAttribute("from") != null + 18268                            && elem.GetAttribute("to") != null;  69  70                case "order":  18071                     if (elem.Document.IsAggregateFetchXml()) @@ -141,244 +141,244 @@

D:  79                    }  80  81                case "condition": - 88582                    return elem.GetAttribute("attribute") != null - 88583                           && elem.GetAttribute("operator") != null; + 89582                    return elem.GetAttribute("attribute") != null + 89583                           && elem.GetAttribute("operator") != null;  84  85                default:  686                    throw new Exception(string.Format("Node {0} is not a valid FetchXml node or it doesn't have the requ  87            } - 626988        } + 632988        }  89  90        public static XAttribute GetAttribute(this XElement elem, string sAttributeName) - 2271191        { - 7005392            return elem.Attributes().FirstOrDefault((a => a.Name.LocalName.Equals(sAttributeName))); - 2271193        } + 2301691        { + 7094892            return elem.Attributes().FirstOrDefault((a => a.Name.LocalName.Equals(sAttributeName))); + 2301693        }  94  95        public static ColumnSet ToColumnSet(this XElement el) - 116696        { - 116697            var allAttributes = el.Elements() - 435298                    .Where(e => e.Name.LocalName.Equals("all-attributes")) - 116699                    .FirstOrDefault(); + 118696        { + 118697            var allAttributes = el.Elements() + 440298                    .Where(e => e.Name.LocalName.Equals("all-attributes")) + 118699                    .FirstOrDefault();  100 - 1166101             if (allAttributes != null) + 1186101             if (allAttributes != null)  18102            {  18103                return new ColumnSet(true);  104            }  105 - 1148106            var attributes = el.Elements() - 4316107                                .Where(e => e.Name.LocalName.Equals("attribute")) - 3216108                                .Select(e => e.GetAttribute("name").Value) - 1148109                                .ToArray(); + 1168106            var attributes = el.Elements() + 4366107                                .Where(e => e.Name.LocalName.Equals("attribute")) + 3246108                                .Select(e => e.GetAttribute("name").Value) + 1168109                                .ToArray();  110  111 - 1148112            return new ColumnSet(attributes); - 1166113        } + 1168112            return new ColumnSet(attributes); + 1186113        }  114  115        public static int? ToTopCount(this XElement el) - 964116        { - 964117            var countAttr = el.GetAttribute("top"); - 1922118             if (countAttr == null) return null; + 974116        { + 974117            var countAttr = el.GetAttribute("top"); + 1932118             if (countAttr == null) return null;  119  120            int iCount; - 6121             if (!int.TryParse(countAttr.Value, out iCount)) + 16121             if (!int.TryParse(countAttr.Value, out iCount))  0122                throw new Exception("Top attribute in fetch node must be an integer");  123 - 6124            return iCount; - 964125        } + 16124            return iCount; + 974125        }  126  127        public static int? ToCount(this XElement el) - 964128        { - 964129            var countAttr = el.GetAttribute("count"); - 1892130             if (countAttr == null) return null; + 974128        { + 974129            var countAttr = el.GetAttribute("count"); + 1912130             if (countAttr == null) return null;  131  132            int iCount;  36133             if (!int.TryParse(countAttr.Value, out iCount))  6134                throw new Exception("Count attribute in fetch node must be an integer");  135  30136            return iCount; - 958137        } + 968137        }  138  139  140        public static bool ToReturnTotalRecordCount(this XElement el) - 958141        { - 958142            var returnTotalRecordCountAttr = el.GetAttribute("returntotalrecordcount"); - 1910143             if (returnTotalRecordCountAttr == null) return false; + 968141        { + 968142            var returnTotalRecordCountAttr = el.GetAttribute("returntotalrecordcount"); + 1930143             if (returnTotalRecordCountAttr == null) return false;  144  145            bool bReturnCount;  6146             if (!bool.TryParse(returnTotalRecordCountAttr.Value, out bReturnCount))  0147                throw new Exception("returntotalrecordcount attribute in fetch node must be an boolean");  148  6149            return bReturnCount; - 958150        } + 968150        }  151  152        public static int? ToPageNumber(this XElement el) - 958153        { - 958154            var pageAttr = el.GetAttribute("page"); - 1892155             if (pageAttr == null) return null; + 968153        { + 968154            var pageAttr = el.GetAttribute("page"); + 1912155             if (pageAttr == null) return null;  156  157            int iPage;  24158             if (!int.TryParse(pageAttr.Value, out iPage))  0159                throw new Exception("Count attribute in fetch node must be an integer");  160  24161            return iPage; - 958162        } + 968162        }  163  164        public static ColumnSet ToColumnSet(this XDocument xlDoc) - 994165        { + 1004165        {  166            //Check if all-attributes exist - 994167            return xlDoc.Elements()   //fetch - 994168                    .Elements() - 994169                    .FirstOrDefault() - 994170                    .ToColumnSet(); - 994171        } + 1004167            return xlDoc.Elements()   //fetch + 1004168                    .Elements() + 1004169                    .FirstOrDefault() + 1004170                    .ToColumnSet(); + 1004171        }  172  173  174        public static int? ToTopCount(this XDocument xlDoc) - 964175        { + 974175        {  176            //Check if all-attributes exist - 964177            return xlDoc.Elements()   //fetch - 964178                    .FirstOrDefault() - 964179                    .ToTopCount(); - 964180        } + 974177            return xlDoc.Elements()   //fetch + 974178                    .FirstOrDefault() + 974179                    .ToTopCount(); + 974180        }  181  182        public static int? ToCount(this XDocument xlDoc) - 964183        { + 974183        {  184            //Check if all-attributes exist - 964185            return xlDoc.Elements()   //fetch - 964186                    .FirstOrDefault() - 964187                    .ToCount(); - 958188        } + 974185            return xlDoc.Elements()   //fetch + 974186                    .FirstOrDefault() + 974187                    .ToCount(); + 968188        }  189  190        public static bool ToReturnTotalRecordCount(this XDocument xlDoc) - 958191        { - 958192            return xlDoc.Elements()   //fetch - 958193                    .FirstOrDefault() - 958194                    .ToReturnTotalRecordCount(); - 958195        } + 968191        { + 968192            return xlDoc.Elements()   //fetch + 968193                    .FirstOrDefault() + 968194                    .ToReturnTotalRecordCount(); + 968195        }  196  197  198        public static int? ToPageNumber(this XDocument xlDoc) - 958199        { + 968199        {  200            //Check if all-attributes exist - 958201            return xlDoc.Elements()   //fetch - 958202                    .FirstOrDefault() - 958203                    .ToPageNumber(); - 958204        } + 968201            return xlDoc.Elements()   //fetch + 968202                    .FirstOrDefault() + 968203                    .ToPageNumber(); + 968204        }  205  206        public static FilterExpression ToCriteria(this XDocument xlDoc, XrmFakedContext ctx) - 994207        { - 994208            return xlDoc.Elements()   //fetch - 994209                    .Elements()     //entity - 994210                    .Elements()     //child nodes of entity - 3888211                    .Where(el => el.Name.LocalName.Equals("filter")) - 1700212                    .Select(el => el.ToFilterExpression(ctx)) - 994213                    .FirstOrDefault(); - 964214        } + 1004207        { + 1004208            return xlDoc.Elements()   //fetch + 1004209                    .Elements()     //entity + 1004210                    .Elements()     //child nodes of entity + 3908211                    .Where(el => el.Name.LocalName.Equals("filter")) + 1720212                    .Select(el => el.ToFilterExpression(ctx)) + 1004213                    .FirstOrDefault(); + 974214        }  215  216        public static string GetAssociatedEntityNameForConditionExpression(this XElement el) - 885217        { + 895217        {  218 - 1830219             while (el != null) - 1830220            { - 1830221                var parent = el.Parent; - 1830222                 if (parent.Name.LocalName.Equals("entity") || parent.Name.LocalName.Equals("link-entity")) - 885223                { - 885224                    return parent.GetAttribute("name").Value; + 1850219             while (el != null) + 1850220            { + 1850221                var parent = el.Parent; + 1850222                 if (parent.Name.LocalName.Equals("entity") || parent.Name.LocalName.Equals("link-entity")) + 895223                { + 895224                    return parent.GetAttribute("name").Value;  225                } - 945226                el = parent; - 945227            } + 955226                el = parent; + 955227            }  228  0229            return null; - 885230        } + 895230        }  231  232        public static LinkEntity ToLinkEntity(this XElement el, XrmFakedContext ctx) - 172233        { + 182233        {  234            //Create this node - 172235            var linkEntity = new LinkEntity(); + 182235            var linkEntity = new LinkEntity();  236 - 172237            linkEntity.LinkFromEntityName = el.Parent.GetAttribute("name").Value; - 172238            linkEntity.LinkFromAttributeName = el.GetAttribute("to").Value; - 172239            linkEntity.LinkToAttributeName = el.GetAttribute("from").Value; - 172240            linkEntity.LinkToEntityName = el.GetAttribute("name").Value; + 182237            linkEntity.LinkFromEntityName = el.Parent.GetAttribute("name").Value; + 182238            linkEntity.LinkFromAttributeName = el.GetAttribute("to").Value; + 182239            linkEntity.LinkToAttributeName = el.GetAttribute("from").Value; + 182240            linkEntity.LinkToEntityName = el.GetAttribute("name").Value;  241 - 172242             if (el.GetAttribute("alias") != null) - 154243            { - 154244                linkEntity.EntityAlias = el.GetAttribute("alias").Value; - 154245            } + 182242             if (el.GetAttribute("alias") != null) + 159243            { + 159244                linkEntity.EntityAlias = el.GetAttribute("alias").Value; + 159245            }  246  247            //Join operator - 172248             if (el.GetAttribute("link-type") != null) - 100249            { - 100250                 switch (el.GetAttribute("link-type").Value) + 182248             if (el.GetAttribute("link-type") != null) + 110249            { + 110250                 switch (el.GetAttribute("link-type").Value)  251                {  252                    case "outer":  30253                        linkEntity.JoinOperator = JoinOperator.LeftOuter;  30254                        break;  255                    default: - 70256                        linkEntity.JoinOperator = JoinOperator.Inner; - 70257                        break; + 80256                        linkEntity.JoinOperator = JoinOperator.Inner; + 80257                        break;  258                } - 100259            } + 110259            }  260  261            //Process other link entities recursively - 172262            var convertedLinkEntityNodes = el.Elements() - 440263                                .Where(e => e.Name.LocalName.Equals("link-entity")) - 190264                                .Select(e => e.ToLinkEntity(ctx)) - 172265                                .ToList(); + 182262            var convertedLinkEntityNodes = el.Elements() + 460263                                .Where(e => e.Name.LocalName.Equals("link-entity")) + 200264                                .Select(e => e.ToLinkEntity(ctx)) + 182265                                .ToList();  266 - 552267            foreach (var le in convertedLinkEntityNodes) + 582267            foreach (var le in convertedLinkEntityNodes)  18268            {  18269                linkEntity.LinkEntities.Add(le);  18270            }  271  272            //Process column sets - 172273            linkEntity.Columns = el.ToColumnSet(); + 182273            linkEntity.Columns = el.ToColumnSet();  274  275            //Process filter - 172276            linkEntity.LinkCriteria = el.Elements() - 440277                                        .Where(e => e.Name.LocalName.Equals("filter")) - 232278                                        .Select(e => e.ToFilterExpression(ctx)) - 172279                                        .FirstOrDefault(); + 182276            linkEntity.LinkCriteria = el.Elements() + 460277                                        .Where(e => e.Name.LocalName.Equals("filter")) + 242278                                        .Select(e => e.ToFilterExpression(ctx)) + 182279                                        .FirstOrDefault();  280 - 172281            return linkEntity; - 172282        } + 182281            return linkEntity; + 182282        }  283  284        public static List<LinkEntity> ToLinkEntities(this XDocument xlDoc, XrmFakedContext ctx) - 958285        { - 958286            return xlDoc.Elements()   //fetch - 958287                    .Elements()     //entity - 958288                    .Elements()     //child nodes of entity - 3804289                    .Where(el => el.Name.LocalName.Equals("link-entity")) - 1112290                    .Select(el => el.ToLinkEntity(ctx)) - 958291                    .ToList(); - 958292        } + 968285        { + 968286            return xlDoc.Elements()   //fetch + 968287                    .Elements()     //entity + 968288                    .Elements()     //child nodes of entity + 3834289                    .Where(el => el.Name.LocalName.Equals("link-entity")) + 1132290                    .Select(el => el.ToLinkEntity(ctx)) + 968291                    .ToList(); + 968292        }  293  294        public static List<OrderExpression> ToOrderExpressionList(this XDocument xlDoc) - 850295        { - 850296            var orderByElements = xlDoc.Elements()   //fetch - 850297                                .Elements()     //entity - 850298                                .Elements()     //child nodes of entity - 3540299                                .Where(el => el.Name.LocalName.Equals("order")) - 850300                                .Select(el => - 994301                                         new OrderExpression - 994302                                        { - 994303                                            AttributeName = el.GetAttribute("attribute").Value, - 994304                                            OrderType = el.IsAttributeTrue("descending") ? OrderType.Descending : OrderT - 994305                                        }) - 850306                                .ToList(); + 860295        { + 860296            var orderByElements = xlDoc.Elements()   //fetch + 860297                                .Elements()     //entity + 860298                                .Elements()     //child nodes of entity + 3570299                                .Where(el => el.Name.LocalName.Equals("order")) + 860300                                .Select(el => + 1004301                                         new OrderExpression + 1004302                                        { + 1004303                                            AttributeName = el.GetAttribute("attribute").Value, + 1004304                                            OrderType = el.IsAttributeTrue("descending") ? OrderType.Descending : OrderT + 1004305                                        }) + 860306                                .ToList();  307 - 850308            return orderByElements; - 850309        } + 860308            return orderByElements; + 860309        }  310  311        public static FilterExpression ToFilterExpression(this XElement elem, XrmFakedContext ctx) - 796312        { - 796313            var filterExpression = new FilterExpression(); + 806312        { + 806313            var filterExpression = new FilterExpression();  314 - 796315            var filterType = elem.GetAttribute("type"); - 796316             if (filterType == null) - 48317            { - 48318                filterExpression.FilterOperator = LogicalOperator.And; //By default - 48319            } + 806315            var filterType = elem.GetAttribute("type"); + 806316             if (filterType == null) + 58317            { + 58318                filterExpression.FilterOperator = LogicalOperator.And; //By default + 58319            }  320            else  748321            {  748322                 filterExpression.FilterOperator = filterType.Value.Equals("and") ? @@ -386,28 +386,28 @@

D:  748324            }  325  326            //Process other filters recursively - 796327            var otherFilters = elem - 796328                        .Elements() //child nodes of this filter - 1711329                        .Where(el => el.Name.LocalName.Equals("filter")) - 826330                        .Select(el => el.ToFilterExpression(ctx)) - 796331                        .ToList(); + 806327            var otherFilters = elem + 806328                        .Elements() //child nodes of this filter + 1731329                        .Where(el => el.Name.LocalName.Equals("filter")) + 836330                        .Select(el => el.ToFilterExpression(ctx)) + 806331                        .ToList();  332  333  334            //Process conditions - 796335            var conditions = elem - 796336                        .Elements() //child nodes of this filter - 1711337                        .Where(el => el.Name.LocalName.Equals("condition")) - 1681338                        .Select(el => el.ToConditionExpression(ctx)) - 796339                        .ToList(); + 806335            var conditions = elem + 806336                        .Elements() //child nodes of this filter + 1731337                        .Where(el => el.Name.LocalName.Equals("condition")) + 1701338                        .Select(el => el.ToConditionExpression(ctx)) + 806339                        .ToList();  340 - 4008341            foreach (var c in conditions) - 855342                filterExpression.AddCondition(c); + 4058341            foreach (var c in conditions) + 865342                filterExpression.AddCondition(c);  343 - 2358344            foreach (var f in otherFilters) + 2388344            foreach (var f in otherFilters)  30345                filterExpression.AddFilter(f);  346 - 766347            return filterExpression; - 766348        } + 776347            return filterExpression; + 776348        }  349  350        public static object ToValue(this XElement elem, XrmFakedContext ctx, string sEntityName, string sAttributeName,  96351        { @@ -415,29 +415,29 @@

D:  84353        }  354  355        public static ConditionExpression ToConditionExpression(this XElement elem, XrmFakedContext ctx) - 885356        { - 885357            var conditionExpression = new ConditionExpression(); + 895356        { + 895357            var conditionExpression = new ConditionExpression();  358 - 885359            var conditionEntityName = ""; + 895359            var conditionEntityName = "";  360 - 885361            var attributeName = elem.GetAttribute("attribute").Value; - 885362            ConditionOperator op = ConditionOperator.Equal; + 895361            var attributeName = elem.GetAttribute("attribute").Value; + 895362            ConditionOperator op = ConditionOperator.Equal;  363 - 885364            string value = null; - 885365             if (elem.GetAttribute("value") != null) - 641366            { - 641367                value = elem.GetAttribute("value").Value; - 641368            } - 885369             if (elem.GetAttribute("entityname") != null) - 10370            { - 10371                conditionEntityName = elem.GetAttribute("entityname").Value; - 10372            } + 895364            string value = null; + 895365             if (elem.GetAttribute("value") != null) + 651366            { + 651367                value = elem.GetAttribute("value").Value; + 651368            } + 895369             if (elem.GetAttribute("entityname") != null) + 20370            { + 20371                conditionEntityName = elem.GetAttribute("entityname").Value; + 20372            }  373 - 885374             switch (elem.GetAttribute("operator").Value) + 895374             switch (elem.GetAttribute("operator").Value)  375            {  376                case "eq": - 353377                    op = ConditionOperator.Equal; - 353378                    break; + 363377                    op = ConditionOperator.Equal; + 363378                    break;  379                case "ne":  380                case "neq":  24381                    op = ConditionOperator.NotEqual; @@ -595,30 +595,30 @@

D:  533            }  534  535            //Process values - 885536            object[] values = null; + 895536            object[] values = null;  537  538 - 885539            var entityName = GetAssociatedEntityNameForConditionExpression(elem); + 895539            var entityName = GetAssociatedEntityNameForConditionExpression(elem);  540  541            //Find values inside the condition expression, if apply - 885542            values = elem - 885543                        .Elements() //child nodes of this filter - 981544                        .Where(el => el.Name.LocalName.Equals("value")) - 981545                        .Select(el => el.ToValue(ctx, entityName, attributeName, op)) - 885546                        .ToArray(); + 895542            values = elem + 895543                        .Elements() //child nodes of this filter + 991544                        .Where(el => el.Name.LocalName.Equals("value")) + 991545                        .Select(el => el.ToValue(ctx, entityName, attributeName, op)) + 895546                        .ToArray();  547  548  549            //Otherwise, a single value was used - 873550             if (value != null) - 641551            { + 883550             if (value != null) + 651551            {  552#if FAKE_XRM_EASY_2013 || FAKE_XRM_EASY_2015 || FAKE_XRM_EASY_2016 || FAKE_XRM_EASY_365 || FAKE_XRM_EASY_9 - 535553                 if (string.IsNullOrWhiteSpace(conditionEntityName)) + 545553                 if (string.IsNullOrWhiteSpace(conditionEntityName))  535554                {  535555                    return new ConditionExpression(attributeName, op, GetConditionExpressionValueCast(value, ctx, entity  556                }  557                else - 0558                { - 0559                    return new ConditionExpression(conditionEntityName, attributeName, op, GetConditionExpressionValueCa + 10558                { + 10559                    return new ConditionExpression(conditionEntityName, attributeName, op, GetConditionExpressionValueCa  560                }  561  562#else @@ -643,7 +643,7 @@

D:  581  582  583 - 855584        } + 865584        }  585  586  587        public static object GetValueBasedOnType(Type t, string value) @@ -790,8 +790,8 @@

D:  587728        }  729  730        public static object GetConditionExpressionValueCast(string value, XrmFakedContext ctx, string sEntityName, stri - 737731        { - 737732             if (ctx.ProxyTypesAssembly != null) + 747731        { + 747732             if (ctx.ProxyTypesAssembly != null)  587733            {  734                //We have proxy types so get appropiate type value based on entity name and attribute type  587735                var reflectedType = ctx.FindReflectedType(sEntityName); @@ -823,8 +823,8 @@

D:  761  762  763            //Try parsing a guid - 150764            Guid gOut = Guid.Empty; - 150765             if (Guid.TryParse(value, out gOut)) + 160764            Guid gOut = Guid.Empty; + 160765             if (Guid.TryParse(value, out gOut))  6766                return gOut;  767  768            //Try checking if it is a numeric value, cause, from the fetchxml it @@ -832,37 +832,37 @@

D:  770            // ex: "123" might compared as a string, or, as an int, it will depend on the attribute  771            //    data type, therefore, in this case we do need to use proxy types  772 - 144773            bool bIsNumeric = false; - 144774            bool bIsDateTime = false; - 144775            double dblValue = 0.0; - 144776            decimal decValue = 0.0m; - 144777            int intValue = 0; + 154773            bool bIsNumeric = false; + 154774            bool bIsDateTime = false; + 154775            double dblValue = 0.0; + 154776            decimal decValue = 0.0m; + 154777            int intValue = 0;  778 - 144779             if (double.TryParse(value, out dblValue)) + 154779             if (double.TryParse(value, out dblValue))  6780                bIsNumeric = true;  781 - 144782             if (decimal.TryParse(value, out decValue)) + 154782             if (decimal.TryParse(value, out decValue))  6783                bIsNumeric = true;  784 - 144785             if (int.TryParse(value, out intValue)) + 154785             if (int.TryParse(value, out intValue))  0786                bIsNumeric = true;  787 - 144788            DateTime dtValue = DateTime.MinValue; - 144789             if (DateTime.TryParse(value, out dtValue)) + 154788            DateTime dtValue = DateTime.MinValue; + 154789             if (DateTime.TryParse(value, out dtValue))  18790                bIsDateTime = true;  791 - 144792             if (bIsNumeric || bIsDateTime) + 154792             if (bIsNumeric || bIsDateTime)  18793            {  18794                throw new Exception("When using arithmetic values in Fetch a ProxyTypesAssembly must be used in order to  795            }  796  797            //Default value - 126798            return value; - 707799        } + 136798            return value; + 717799        }  800    }  801} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_XrmFakedContext.htm b/test/reports/FakeXrmEasy_XrmFakedContext.htm index f9fd7090..ec4bd585 100644 --- a/test/reports/FakeXrmEasy_XrmFakedContext.htm +++ b/test/reports/FakeXrmEasy_XrmFakedContext.htm @@ -15,11 +15,11 @@

Summary

Class:FakeXrmEasy.XrmFakedContext Assembly:FakeXrmEasy File(s):D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedContext.Aggregations.cs
D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedContext.CodeActivities.cs
D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedContext.Crud.cs
D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedContext.cs
D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedContext.DateTime.cs
D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedContext.Metadata.cs
D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedContext.Pipeline.cs
D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedContext.Plugins.cs
D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedContext.Queries.cs -Covered lines:2461 -Uncovered lines:313 -Coverable lines:2774 -Total lines:4557 -Line coverage:88.7% +Covered lines:2530 +Uncovered lines:318 +Coverable lines:2848 +Total lines:4651 +Line coverage:88.8% Branch coverage:72.5% @@ -105,7 +105,7 @@

Metrics

InitializeMetadata(...)1100100 InitializeMetadata(...)210066.67 CreateMetadataQuery()2100100 -GetEntityMetadataByName(...)1100100 +GetEntityMetadataByName(...)2100100 SetEntityMetadata(...)28066.67 GetAttributeMetadataFor(...)400 GetDefaultPluginContext()310080 @@ -189,6 +189,12 @@

Metrics

TranslateQueryExpressionFiltersToExpression(...)8100100 TranslateFilterExpressionToExpression(...)11100100 TranslateConditionExpressionNext(...)576.4757.14 +ValidateAliases(...)510080 +ValidateAliases(...)510080 +ValidateAliases(...)810071.43 +ValidateAliases(...)97566.67 +MatchByEntity(...)610060 +MatchByAlias(...)510080 GetFakedEntityDataSourceRetrieverService()1100100 ConvertToHashSetOfInt(...)2481.6380 TranslateConditionExpressionContainValues(...)1100100 @@ -924,7 +930,7 @@

D:\Git\fake-xrm-e  16        protected const int EntityActiveStateCode = 0;  17        protected const int EntityInactiveStateCode = 1;  18 - 9570819        public bool ValidateReferences { get; set; } + 9609619        public bool ValidateReferences { get; set; }  20  21        #region CRUD  22        public Guid GetRecordUniqueId(EntityReference record, bool validate = true) @@ -997,44 +1003,44 @@

D:\Git\fake-xrm-e  89        /// <param name="fakedService">The faked service where the Retrieve method will be faked</param>  90        /// <returns></returns>  91        protected static void FakeRetrieve(XrmFakedContext context, IOrganizationService fakedService) - 301992        { - 301993            A.CallTo(() => fakedService.Retrieve(A<string>._, A<Guid>._, A<ColumnSet>._)) - 301994                .ReturnsLazily((string entityName, Guid id, ColumnSet columnSet) => - 370195                { - 370196                    RetrieveRequest retrieveRequest = new RetrieveRequest() - 370197                    { - 370198                        Target = new EntityReference() { LogicalName = entityName, Id = id }, - 370199                        ColumnSet = columnSet - 3701100                    }; - 3701101                    var executor = context.FakeMessageExecutors[typeof(RetrieveRequest)]; - 3019102 - 3701103                    RetrieveResponse retrieveResponse = (RetrieveResponse)executor.Execute(retrieveRequest, context); - 3019104 - 3635105                    return retrieveResponse.Entity; - 3635106                }); - 3019107        } + 306992        { + 306993            A.CallTo(() => fakedService.Retrieve(A<string>._, A<Guid>._, A<ColumnSet>._)) + 306994                .ReturnsLazily((string entityName, Guid id, ColumnSet columnSet) => + 375195                { + 375196                    RetrieveRequest retrieveRequest = new RetrieveRequest() + 375197                    { + 375198                        Target = new EntityReference() { LogicalName = entityName, Id = id }, + 375199                        ColumnSet = columnSet + 3751100                    }; + 3751101                    var executor = context.FakeMessageExecutors[typeof(RetrieveRequest)]; + 3069102 + 3751103                    RetrieveResponse retrieveResponse = (RetrieveResponse)executor.Execute(retrieveRequest, context); + 3069104 + 3685105                    return retrieveResponse.Entity; + 3685106                }); + 3069107        }  108        /// <summary>  109        /// Fakes the Create message  110        /// </summary>  111        /// <param name="context"></param>  112        /// <param name="fakedService"></param>  113        protected static void FakeCreate(XrmFakedContext context, IOrganizationService fakedService) - 3019114        { - 3019115            A.CallTo(() => fakedService.Create(A<Entity>._)) - 3019116                .ReturnsLazily((Entity e) => - 4271117                { - 4271118                    return context.CreateEntity(e); - 4211119                }); - 3019120        } + 3069114        { + 3069115            A.CallTo(() => fakedService.Create(A<Entity>._)) + 3069116                .ReturnsLazily((Entity e) => + 4333117                { + 4333118                    return context.CreateEntity(e); + 4273119                }); + 3069120        }  121  122        protected static void FakeUpdate(XrmFakedContext context, IOrganizationService fakedService) - 3019123        { - 3019124            A.CallTo(() => fakedService.Update(A<Entity>._)) - 3019125                .Invokes((Entity e) => - 3355126                { - 3355127                    context.UpdateEntity(e); - 3319128                }); - 3019129        } + 3069123        { + 3069124            A.CallTo(() => fakedService.Update(A<Entity>._)) + 3069125                .Invokes((Entity e) => + 3405126                { + 3405127                    context.UpdateEntity(e); + 3369128                }); + 3069129        }  130  131        protected void UpdateEntity(Entity e)  336132        { @@ -1130,25 +1136,25 @@

D:\Git\fake-xrm-e  222        /// <param name="context"></param>  223        /// <param name="fakedService"></param>  224        protected static void FakeDelete(XrmFakedContext context, IOrganizationService fakedService) - 3019225        { - 3019226            A.CallTo(() => fakedService.Delete(A<string>._, A<Guid>._)) - 3019227                .Invokes((string entityName, Guid id) => - 3163228                { - 3163229                     if (string.IsNullOrWhiteSpace(entityName)) - 3037230                    { - 3037231                        throw new InvalidOperationException("The entity logical name must not be null or empty."); - 3019232                    } - 3019233 - 3145234                     if (id == Guid.Empty) - 3025235                    { - 3025236                        throw new InvalidOperationException("The id must not be empty."); - 3019237                    } - 3019238 - 3139239                    var entityReference = new EntityReference(entityName, id); - 3019240 - 3139241                    context.DeleteEntity(entityReference); - 3121242                }); - 3019243        } + 3069225        { + 3069226            A.CallTo(() => fakedService.Delete(A<string>._, A<Guid>._)) + 3069227                .Invokes((string entityName, Guid id) => + 3213228                { + 3213229                     if (string.IsNullOrWhiteSpace(entityName)) + 3087230                    { + 3087231                        throw new InvalidOperationException("The entity logical name must not be null or empty."); + 3069232                    } + 3069233 + 3195234                     if (id == Guid.Empty) + 3075235                    { + 3075236                        throw new InvalidOperationException("The id must not be empty."); + 3069237                    } + 3069238 + 3189239                    var entityReference = new EntityReference(entityName, id); + 3069240 + 3189241                    context.DeleteEntity(entityReference); + 3171242                }); + 3069243        }  244  245        protected void DeleteEntity(EntityReference er)  120246        { @@ -1195,35 +1201,35 @@

D:\Git\fake-xrm-e  287  288        #region Other protected methods  289        protected void EnsureEntityNameExistsInMetadata(string sEntityName) - 5901290        { - 6381291             if (Relationships.Values.Any(value => new[] { value.Entity1LogicalName, value.Entity2LogicalName, value.Inte + 6015290        { + 6495291             if (Relationships.Values.Any(value => new[] { value.Entity1LogicalName, value.Entity2LogicalName, value.Inte  456292            {  456293                return;  294            }  295  296            // Entity metadata is checked differently when we are using a ProxyTypesAssembly => we can infer that from t - 5445297             if (ProxyTypesAssembly != null) - 4014298            { - 4014299                var subClassType = FindReflectedType(sEntityName); - 4014300                 if (subClassType == null) + 5559297             if (ProxyTypesAssembly != null) + 4032298            { + 4032299                var subClassType = FindReflectedType(sEntityName); + 4032300                 if (subClassType == null)  0301                {  0302                    throw new Exception($"Entity {sEntityName} does not exist in the metadata cache");  303                } - 4014304            } + 4032304            }  305            //else if (!Data.ContainsKey(sEntityName))  306            //{  307            //    //No Proxy Types Assembly  308            //    throw new Exception(string.Format("Entity {0} does not exist in the metadata cache", sEntityName));  309            //}; - 5901310        } + 6015310        }  311  312        protected void AddEntityDefaultAttributes(Entity e) - 28034313        { + 28146313        {  314            // Add createdon, modifiedon, createdby, modifiedby properties - 28034315             if (CallerId == null) - 2826316            { - 2826317                CallerId = new EntityReference("systemuser", Guid.NewGuid()); // Create a new instance by default - 2826318                 if (ValidateReferences) + 28146315             if (CallerId == null) + 2876316            { + 2876317                CallerId = new EntityReference("systemuser", Guid.NewGuid()); // Create a new instance by default + 2876318                 if (ValidateReferences)  33319                {  33320                     if (!Data.ContainsKey("systemuser"))  33321                    { @@ -1235,71 +1241,71 @@

D:\Git\fake-xrm-e  33327                    }  33328                }  329 - 2826330            } + 2876330            }  331 - 28034332            var isManyToManyRelationshipEntity = e.LogicalName != null && this.Relationships.ContainsKey(e.LogicalName); + 28146332            var isManyToManyRelationshipEntity = e.LogicalName != null && this.Relationships.ContainsKey(e.LogicalName);  333 - 28034334            EntityInitializerService.Initialize(e, CallerId.Id, this, isManyToManyRelationshipEntity); - 28034335        } + 28146334            EntityInitializerService.Initialize(e, CallerId.Id, this, isManyToManyRelationshipEntity); + 28146335        }  336  337        protected void ValidateEntity(Entity e) - 29310338        { - 29310339             if (e == null) + 29434338        { + 29434339             if (e == null)  0340            {  0341                throw new InvalidOperationException("The entity must not be null");  342            }  343  344            // Validate the entity - 29310345             if (string.IsNullOrWhiteSpace(e.LogicalName)) + 29434345             if (string.IsNullOrWhiteSpace(e.LogicalName))  12346            {  12347                throw new InvalidOperationException("The LogicalName property must not be empty");  348            }  349 - 29298350             if (e.Id == Guid.Empty) + 29422350             if (e.Id == Guid.Empty)  6351            {  6352                throw new InvalidOperationException("The Id property must not be empty");  353            } - 29292354        } + 29416354        }  355  356        protected internal Guid CreateEntity(Entity e) - 1282357        { - 1282358             if (e == null) + 1294357        { + 1294358             if (e == null)  6359            {  6360                throw new InvalidOperationException("The entity must not be null");  361            }  362 - 1276363            var clone = e.Clone(e.GetType()); + 1288363            var clone = e.Clone(e.GetType());  364 - 1276365             if (clone.Id == Guid.Empty) - 982366            { - 982367                clone.Id = Guid.NewGuid(); // Add default guid if none present - 982368            } + 1288365             if (clone.Id == Guid.Empty) + 994366            { + 994367                clone.Id = Guid.NewGuid(); // Add default guid if none present + 994368            }  369  370            // Hack for Dynamic Entities where the Id property doesn't populate the "entitynameid" primary key - 1276371            var primaryKeyAttribute = $"{e.LogicalName}id"; - 1276372             if (!clone.Attributes.ContainsKey(primaryKeyAttribute)) - 772373            { - 772374                clone[primaryKeyAttribute] = clone.Id; - 772375            } + 1288371            var primaryKeyAttribute = $"{e.LogicalName}id"; + 1288372             if (!clone.Attributes.ContainsKey(primaryKeyAttribute)) + 784373            { + 784374                clone[primaryKeyAttribute] = clone.Id; + 784375            }  376 - 1276377            ValidateEntity(clone); + 1288377            ValidateEntity(clone);  378  379            // Create specific validations - 1270380             if (clone.Id != Guid.Empty && Data.ContainsKey(clone.LogicalName) && - 1270381                Data[clone.LogicalName].ContainsKey(clone.Id)) + 1282380             if (clone.Id != Guid.Empty && Data.ContainsKey(clone.LogicalName) && + 1282381                Data[clone.LogicalName].ContainsKey(clone.Id))  24382            {  24383                throw new InvalidOperationException($"There is already a record of entity {clone.LogicalName} with id {c  384            }  385  386            // Create specific validations - 1246387             if (clone.Attributes.ContainsKey("statecode")) + 1258387             if (clone.Attributes.ContainsKey("statecode"))  6388            {  6389                throw new InvalidOperationException($"When creating an entity with logical name '{clone.LogicalName}', o  390            }  391 - 1240392            AddEntityWithDefaults(clone, false, this.UsePipelineSimulation); + 1252392            AddEntityWithDefaults(clone, false, this.UsePipelineSimulation);  393 - 1228394             if (e.RelatedEntities.Count > 0) + 1240394             if (e.RelatedEntities.Count > 0)  18395            {  84396                foreach (var relationshipSet in e.RelatedEntities)  18397                { @@ -1330,128 +1336,128 @@

D:\Git\fake-xrm-e  12422                }  12423            }  424 - 1222425            return clone.Id; - 1222426        } + 1234425            return clone.Id; + 1234426        }  427  428        protected internal void AddEntityWithDefaults(Entity e, bool clone = false, bool usePluginPipeline = false) - 28034429        { + 28146429        {  430            // Create the entity with defaults - 28034431            AddEntityDefaultAttributes(e); + 28146431            AddEntityDefaultAttributes(e);  432 - 28034433             if (usePluginPipeline) + 28146433             if (usePluginPipeline)  42434            {  42435                ExecutePipelineStage("Create", ProcessingStepStage.Preoperation, ProcessingStepMode.Synchronous, e);  42436            }  437  438            // Store - 28034439             AddEntity(clone ? e.Clone(e.GetType()) : e); + 28146439             AddEntity(clone ? e.Clone(e.GetType()) : e);  440 - 28010441             if (usePluginPipeline) + 28122441             if (usePluginPipeline)  42442            {  42443                ExecutePipelineStage("Create", ProcessingStepStage.Postoperation, ProcessingStepMode.Synchronous, e);  42444                ExecutePipelineStage("Create", ProcessingStepStage.Postoperation, ProcessingStepMode.Asynchronous, e);  42445            } - 28010446        } + 28122446        }  447  448        protected internal void AddEntity(Entity e) - 28034449        { + 28146449        {  450            //Automatically detect proxy types assembly if an early bound type was used. - 28034451             if (ProxyTypesAssembly == null && - 28034452                e.GetType().IsSubclassOf(typeof(Entity))) - 1420453            { - 1420454                ProxyTypesAssembly = Assembly.GetAssembly(e.GetType()); - 1420455            } + 28146451             if (ProxyTypesAssembly == null && + 28146452                e.GetType().IsSubclassOf(typeof(Entity))) + 1426453            { + 1426454                ProxyTypesAssembly = Assembly.GetAssembly(e.GetType()); + 1426455            }  456 - 28034457            ValidateEntity(e); //Entity must have a logical name and an Id + 28146457            ValidateEntity(e); //Entity must have a logical name and an Id  458 - 523598459            foreach (var sAttributeName in e.Attributes.Keys.ToList()) - 219769460            { - 219769461                var attribute = e[sAttributeName]; - 219769462                 if (attribute is DateTime) - 56810463                { - 56810464                    e[sAttributeName] = ConvertToUtc((DateTime)e[sAttributeName]); - 56810465                } - 219769466                 if (attribute is EntityReference && ValidateReferences) + 525666459            foreach (var sAttributeName in e.Attributes.Keys.ToList()) + 220635460            { + 220635461                var attribute = e[sAttributeName]; + 220635462                 if (attribute is DateTime) + 57010463                { + 57010464                    e[sAttributeName] = ConvertToUtc((DateTime)e[sAttributeName]); + 57010465                } + 220635466                 if (attribute is EntityReference && ValidateReferences)  174467                {  174468                    var target = (EntityReference)e[sAttributeName];  174469                    e[sAttributeName] = ResolveEntityReference(target);  168470                } - 219763471            } + 220629471            }  472  473            //Add the entity collection - 28016474             if (!Data.ContainsKey(e.LogicalName)) - 4645475            { - 4645476                Data.Add(e.LogicalName, new Dictionary<Guid, Entity>()); - 4645477            } + 28128474             if (!Data.ContainsKey(e.LogicalName)) + 4751475            { + 4751476                Data.Add(e.LogicalName, new Dictionary<Guid, Entity>()); + 4751477            }  478 - 28016479             if (Data[e.LogicalName].ContainsKey(e.Id)) + 28128479             if (Data[e.LogicalName].ContainsKey(e.Id))  6480            {  6481                Data[e.LogicalName][e.Id] = e;  6482            }  483            else - 28010484            { - 28010485                Data[e.LogicalName].Add(e.Id, e); - 28010486            } + 28122484            { + 28122485                Data[e.LogicalName].Add(e.Id, e); + 28122486            }  487  488            //Update metadata for that entity - 28016489             if (!AttributeMetadataNames.ContainsKey(e.LogicalName)) - 4645490                AttributeMetadataNames.Add(e.LogicalName, new Dictionary<string, string>()); + 28128489             if (!AttributeMetadataNames.ContainsKey(e.LogicalName)) + 4751490                AttributeMetadataNames.Add(e.LogicalName, new Dictionary<string, string>());  491  492            //Update attribute metadata - 28016493             if (ProxyTypesAssembly != null) - 6128494            { + 28128493             if (ProxyTypesAssembly != null) + 6140494            {  495                //If the context is using a proxy types assembly then we can just guess the metadata from the generated  - 6128496                var type = FindReflectedType(e.LogicalName); - 6128497                 if (type != null) - 6122498                { - 6122499                    var props = type.GetProperties(); - 3071728500                    foreach (var p in props) - 1526681501                    { - 1526681502                         if (!AttributeMetadataNames[e.LogicalName].ContainsKey(p.Name)) - 741897503                            AttributeMetadataNames[e.LogicalName].Add(p.Name, p.Name); - 1526681504                    } - 6122505                } + 6140496                var type = FindReflectedType(e.LogicalName); + 6140497                 if (type != null) + 6134498                { + 6134499                    var props = type.GetProperties(); + 3077742500                    foreach (var p in props) + 1529670501                    { + 1529670502                         if (!AttributeMetadataNames[e.LogicalName].ContainsKey(p.Name)) + 744886503                            AttributeMetadataNames[e.LogicalName].Add(p.Name, p.Name); + 1529670504                    } + 6134505                }  506                else  6507                    throw new Exception(string.Format("Couldnt find reflected type for {0}", e.LogicalName));  508 - 6122509            } + 6134509            }  510            else - 21888511            { + 21988511            {  512                //If dynamic entities are being used, then the only way of guessing if a property exists is just by chec  513                //if the entity has the attribute in the dictionary - 404778514                foreach (var attKey in e.Attributes.Keys) - 169557515                { - 169557516                     if (!AttributeMetadataNames[e.LogicalName].ContainsKey(attKey)) - 14527517                        AttributeMetadataNames[e.LogicalName].Add(attKey, attKey); - 169557518                } - 21888519            } + 406594514                foreach (var attKey in e.Attributes.Keys) + 170315515                { + 170315516                     if (!AttributeMetadataNames[e.LogicalName].ContainsKey(attKey)) + 15237517                        AttributeMetadataNames[e.LogicalName].Add(attKey, attKey); + 170315518                } + 21988519            }  520 - 28010521        } + 28122521        }  522  523        protected internal bool AttributeExistsInMetadata(string sEntityName, string sAttributeName) - 6064524        { - 6376525            var relationships = this.Relationships.Values.Where(value => new[] { value.Entity1LogicalName, value.Entity2 - 6340526             if (relationships.Any(e => e.Entity1Attribute == sAttributeName || e.Entity2Attribute == sAttributeName)) + 6120524        { + 6432525            var relationships = this.Relationships.Values.Where(value => new[] { value.Entity1LogicalName, value.Entity2 + 6396526             if (relationships.Any(e => e.Entity1Attribute == sAttributeName || e.Entity2Attribute == sAttributeName))  102527            {  102528                return true;  529            }  530  531            //Early bound types - 5962532             if (ProxyTypesAssembly != null) - 5022533            { + 6018532             if (ProxyTypesAssembly != null) + 5034533            {  534                //Check if attribute exists in the early bound type - 5022535                var earlyBoundType = FindReflectedType(sEntityName); - 5022536                 if (earlyBoundType != null) - 5022537                { + 5034535                var earlyBoundType = FindReflectedType(sEntityName); + 5034536                 if (earlyBoundType != null) + 5034537                {  538                    //Get that type properties - 5022539                    var attributeFound = earlyBoundType - 5022540                        .GetProperties() - 456868541                        .Where(pi => pi.GetCustomAttributes(typeof(AttributeLogicalNameAttribute), true).Length > 0) - 452341542                        .Where(pi => (pi.GetCustomAttributes(typeof(AttributeLogicalNameAttribute), true)[0] as Attribut - 5022543                        .FirstOrDefault(); + 5034539                    var attributeFound = earlyBoundType + 5034540                        .GetProperties() + 458096541                        .Where(pi => pi.GetCustomAttributes(typeof(AttributeLogicalNameAttribute), true).Length > 0) + 453120542                        .Where(pi => (pi.GetCustomAttributes(typeof(AttributeLogicalNameAttribute), true)[0] as Attribut + 5034543                        .FirstOrDefault();  544 - 5022545                     if (attributeFound != null) - 4998546                        return true; + 5034545                     if (attributeFound != null) + 5010546                        return true;  547  24548                     if (attributeFound == null && EntityMetadata.ContainsKey(sEntityName))  0549                    { @@ -1467,15 +1473,15 @@

D:\Git\fake-xrm-e  0559                return false;  560            }  561 - 940562             if (EntityMetadata.ContainsKey(sEntityName)) + 984562             if (EntityMetadata.ContainsKey(sEntityName))  0563            {  564                //Try with metadata  0565                return AttributeExistsInInjectedMetadata(sEntityName, sAttributeName);  566            }  567  568            //Dynamic entities and not entity metadata injected for entity => just return true if not found - 940569            return true; - 6064570        } + 984569            return true; + 6120570        }  571  572        protected internal bool AttributeExistsInInjectedMetadata(string sEntityName, string sAttributeName)  0573        { @@ -1484,9 +1490,9 @@

D:\Git\fake-xrm-e  0576        }  577  578        protected internal DateTime ConvertToUtc(DateTime attribute) - 57133579        { - 57133580            return DateTime.SpecifyKind(attribute, DateTimeKind.Utc); - 57133581        } + 57333579        { + 57333580            return DateTime.SpecifyKind(attribute, DateTimeKind.Utc); + 57333581        }  582        #endregion  583    }  584} @@ -1518,22 +1524,22 @@

D:\Git\fake-xrm-easy\  20    /// </summary>  21    public partial class XrmFakedContext : IXrmContext  22    { - 1122523        protected internal IOrganizationService Service { get; set; } + 1139923        protected internal IOrganizationService Service { get; set; }  24  25        private IServiceEndpointNotificationService _serviceEndpointNotificationService;  26 - 419327        private readonly Lazy<XrmFakedTracingService> _tracingService = new Lazy<XrmFakedTracingService>(() => new XrmFa + 424327        private readonly Lazy<XrmFakedTracingService> _tracingService = new Lazy<XrmFakedTracingService>(() => new XrmFa  28  29        /// <summary>  30        /// All proxy type assemblies available on mocked database.  31        /// </summary> - 13727932        private List<Assembly> ProxyTypesAssemblies { get; set; } + 13806932        private List<Assembly> ProxyTypesAssemblies { get; set; }  33  27134        protected internal XrmFakedTracingService TracingService => _tracingService.Value;  35 - 497636        protected internal bool Initialised { get; set; } + 507636        protected internal bool Initialised { get; set; }  37 - 11210838        public Dictionary<string, Dictionary<Guid, Entity>> Data { get; set; } + 11281238        public Dictionary<string, Dictionary<Guid, Entity>> Data { get; set; }  39  40        /// <summary>  41        /// Specify which assembly is used to search for early-bound proxy @@ -1546,25 +1552,25 @@

D:\Git\fake-xrm-easy\  48        public Assembly ProxyTypesAssembly  49        {  50            get - 10074551            { + 10126751            {  52                // TODO What we should do when ProxyTypesAssemblies contains multiple assemblies? One shouldn't throw ex - 10074553                return ProxyTypesAssemblies.FirstOrDefault(); - 10074554            } + 10126753                return ProxyTypesAssemblies.FirstOrDefault(); + 10126754            }  55            set - 213156            { - 213157                ProxyTypesAssemblies = new List<Assembly>(); - 213158                 if (value != null) - 213159                { - 213160                    ProxyTypesAssemblies.Add(value); - 213161                } - 213162            } + 213756            { + 213757                ProxyTypesAssemblies = new List<Assembly>(); + 213758                 if (value != null) + 213759                { + 213760                    ProxyTypesAssemblies.Add(value); + 213761                } + 213762            }  63        }  64  65        /// <summary>  66        /// Sets the user to assign the CreatedBy and ModifiedBy properties when entities are added to the context.  67        /// All requests will be executed on behalf of this user  68        /// </summary> - 5963069        public EntityReference CallerId { get; set; } + 5990469        public EntityReference CallerId { get; set; }  70  28371        public EntityReference BusinessUnitId { get; set; }  72 @@ -1573,81 +1579,81 @@

D:\Git\fake-xrm-easy\  75        /// <summary>  76        /// Probably should be replaced by FakeMessageExecutors, more generic, which can use custom interfaces rather th  77        /// </summary> - 598078        private Dictionary<Type, ServiceRequestExecution> ExecutionMocks { get; set; } + 603078        private Dictionary<Type, ServiceRequestExecution> ExecutionMocks { get; set; }  79 - 1071880        private Dictionary<Type, IFakeMessageExecutor> FakeMessageExecutors { get; set; } + 1079280        private Dictionary<Type, IFakeMessageExecutor> FakeMessageExecutors { get; set; }  81 - 406682        private Dictionary<string, IFakeMessageExecutor> GenericFakeMessageExecutors { get; set; } + 411682        private Dictionary<string, IFakeMessageExecutor> GenericFakeMessageExecutors { get; set; }  83 - 4473184        private Dictionary<string, XrmFakedRelationship> Relationships { get; set; } + 4509984        private Dictionary<string, XrmFakedRelationship> Relationships { get; set; }  85  86 - 3204087        public IEntityInitializerService EntityInitializerService { get; set; } - 428988        public IAccessRightsRepository AccessRightsRepository { get; set; } + 3220287        public IEntityInitializerService EntityInitializerService { get; set; } + 433988        public IAccessRightsRepository AccessRightsRepository { get; set; }  89 - 1979790        public int MaxRetrieveCount { get; set; } + 1989590        public int MaxRetrieveCount { get; set; }  91 - 3205292        public EntityInitializationLevel InitializationLevel { get; set; } + 3220292        public EntityInitializationLevel InitializationLevel { get; set; }  93 - 400094        public XrmFakedContext() - 400095        { - 400096            MaxRetrieveCount = 5000; + 405094        public XrmFakedContext() + 405095        { + 405096            MaxRetrieveCount = 5000;  97 - 400098            AttributeMetadataNames = new Dictionary<string, Dictionary<string, string>>(); - 400099            Data = new Dictionary<string, Dictionary<Guid, Entity>>(); - 4000100            ExecutionMocks = new Dictionary<Type, ServiceRequestExecution>(); - 4000101            OptionSetValuesMetadata = new Dictionary<string, OptionSetMetadata>(); - 4000102            StatusAttributeMetadata = new Dictionary<string, StatusAttributeMetadata>(); + 405098            AttributeMetadataNames = new Dictionary<string, Dictionary<string, string>>(); + 405099            Data = new Dictionary<string, Dictionary<Guid, Entity>>(); + 4050100            ExecutionMocks = new Dictionary<Type, ServiceRequestExecution>(); + 4050101            OptionSetValuesMetadata = new Dictionary<string, OptionSetMetadata>(); + 4050102            StatusAttributeMetadata = new Dictionary<string, StatusAttributeMetadata>();  103 - 4000104            FakeMessageExecutors = Assembly.GetExecutingAssembly() - 4000105                .GetTypes() - 806476106                .Where(t => t.GetInterfaces().Contains(typeof(IFakeMessageExecutor))) - 185556107                .Select(t => Activator.CreateInstance(t) as IFakeMessageExecutor) - 367112108                .ToDictionary(t => t.GetResponsibleRequestType(), t => t); + 4050104            FakeMessageExecutors = Assembly.GetExecutingAssembly() + 4050105                .GetTypes() + 812531106                .Where(t => t.GetInterfaces().Contains(typeof(IFakeMessageExecutor))) + 187890107                .Select(t => Activator.CreateInstance(t) as IFakeMessageExecutor) + 371730108                .ToDictionary(t => t.GetResponsibleRequestType(), t => t);  109 - 4000110            GenericFakeMessageExecutors = new Dictionary<string, IFakeMessageExecutor>(); + 4050110            GenericFakeMessageExecutors = new Dictionary<string, IFakeMessageExecutor>();  111 - 4000112            Relationships = new Dictionary<string, XrmFakedRelationship>(); + 4050112            Relationships = new Dictionary<string, XrmFakedRelationship>();  113 - 4000114            EntityInitializerService = new DefaultEntityInitializerService(); + 4050114            EntityInitializerService = new DefaultEntityInitializerService();  115 - 4000116            AccessRightsRepository = new AccessRightsRepository(); + 4050116            AccessRightsRepository = new AccessRightsRepository();  117 - 4000118            SystemTimeZone = TimeZoneInfo.Local; - 4000119            DateBehaviour = DefaultDateBehaviour(); + 4050118            SystemTimeZone = TimeZoneInfo.Local; + 4050119            DateBehaviour = DefaultDateBehaviour();  120 - 4000121            EntityMetadata = new Dictionary<string, EntityMetadata>(); + 4050121            EntityMetadata = new Dictionary<string, EntityMetadata>();  122 - 4000123            UsePipelineSimulation = false; + 4050123            UsePipelineSimulation = false;  124 - 4000125            InitializationLevel = EntityInitializationLevel.Default; + 4050125            InitializationLevel = EntityInitializationLevel.Default;  126 - 4000127            ProxyTypesAssemblies = new List<Assembly>(); - 4000128        } + 4050127            ProxyTypesAssemblies = new List<Assembly>(); + 4050128        }  129  130        /// <summary>  131        /// Initializes the context with the provided entities  132        /// </summary>  133        /// <param name="entities"></param>  134        public virtual void Initialize(IEnumerable<Entity> entities) - 2500135        { - 2500136             if (Initialised) + 2550135        { + 2550136             if (Initialised)  6137            {  6138                throw new Exception("Initialize should be called only once per unit test execution and XrmFakedContext i  139            }  140 - 2494141             if (entities == null) + 2544141             if (entities == null)  6142            {  6143                throw new InvalidOperationException("The entities parameter must be not null");  144            }  145 - 60368146            foreach (var e in entities) - 26458147            { - 26458148                AddEntityWithDefaults(e, true); - 26446149            } + 60718146            foreach (var e in entities) + 26558147            { + 26558148                AddEntityWithDefaults(e, true); + 26546149            }  150 - 2476151            Initialised = true; - 2476152        } + 2526151            Initialised = true; + 2526152        }  153  154        public void Initialize(Entity e)  105155        { @@ -1720,9 +1726,9 @@

D:\Git\fake-xrm-easy\  6222        }  223  224        public void AddRelationship(string schemaname, XrmFakedRelationship relationship) - 186225        { - 186226            Relationships.Add(schemaname, relationship); - 186227        } + 198225        { + 198226            Relationships.Add(schemaname, relationship); + 198227        }  228  229        public void RemoveRelationship(string schemaname)  0230        { @@ -1730,14 +1736,14 @@

D:\Git\fake-xrm-easy\  0232        }  233  234        public XrmFakedRelationship GetRelationship(string schemaName) - 282235        { - 282236             if (Relationships.ContainsKey(schemaName)) - 270237            { - 270238                return Relationships[schemaName]; + 294235        { + 294236             if (Relationships.ContainsKey(schemaName)) + 282237            { + 282238                return Relationships[schemaName];  239            }  240  12241            return null; - 282242        } + 294242        }  243  244        public void AddAttributeMapping(string sourceEntityName, string sourceAttributeName, string targetEntityName, st  18245        { @@ -1772,14 +1778,14 @@

D:\Git\fake-xrm-easy\  18274        }  275  276        public virtual IOrganizationService GetOrganizationService() - 2010277        { - 2010278             if (this is XrmRealContext) + 2065277        { + 2065278             if (this is XrmRealContext)  0279            {  0280                Service = GetOrganizationService();  0281                return Service;  282            } - 2010283            return GetFakedOrganizationService(this); - 2010284        } + 2065283            return GetFakedOrganizationService(this); + 2065284        }  285  286        /// <summary>  287        /// Deprecated. Use GetOrganizationService instead @@ -1787,36 +1793,36 @@

D:\Git\fake-xrm-easy\  289        /// <returns></returns>  290        [Obsolete("Use GetOrganizationService instead")]  291        public IOrganizationService GetFakedOrganizationService() - 1823292        { - 1823293            return GetFakedOrganizationService(this); - 1823294        } + 1830292        { + 1830293            return GetFakedOrganizationService(this); + 1830294        }  295  296        protected IOrganizationService GetFakedOrganizationService(XrmFakedContext context) - 3833297        { - 3833298             if (context.Service != null) - 814299            { - 814300                return context.Service; + 3895297        { + 3895298             if (context.Service != null) + 826299            { + 826300                return context.Service;  301            }  302 - 3019303            var fakedService = A.Fake<IOrganizationService>(); + 3069303            var fakedService = A.Fake<IOrganizationService>();  304  305            //Fake CRUD methods - 3019306            FakeRetrieve(context, fakedService); - 3019307            FakeCreate(context, fakedService); - 3019308            FakeUpdate(context, fakedService); - 3019309            FakeDelete(context, fakedService); + 3069306            FakeRetrieve(context, fakedService); + 3069307            FakeCreate(context, fakedService); + 3069308            FakeUpdate(context, fakedService); + 3069309            FakeDelete(context, fakedService);  310  311            //Fake / Intercept Retrieve Multiple Requests - 3019312            FakeRetrieveMultiple(context, fakedService); + 3069312            FakeRetrieveMultiple(context, fakedService);  313  314            //Fake / Intercept other requests - 3019315            FakeExecute(context, fakedService); - 3019316            FakeAssociate(context, fakedService); - 3019317            FakeDisassociate(context, fakedService); - 3019318            context.Service = fakedService; + 3069315            FakeExecute(context, fakedService); + 3069316            FakeAssociate(context, fakedService); + 3069317            FakeDisassociate(context, fakedService); + 3069318            context.Service = fakedService;  319 - 3019320            return context.Service; - 3833321        } + 3069320            return context.Service; + 3895321        }  322  323        /// <summary>  324        /// Fakes the Execute method of the organization service. @@ -1825,87 +1831,87 @@

D:\Git\fake-xrm-easy\  327        /// <param name="context"></param>  328        /// <param name="fakedService"></param>  329        public static void FakeExecute(XrmFakedContext context, IOrganizationService fakedService) - 3019330        { - 3019331            OrganizationResponse response = null; - 3019332            Func<OrganizationRequest, OrganizationResponse> execute = (req) => - 4939333            { - 4939334                 if (context.ExecutionMocks.ContainsKey(req.GetType())) - 3031335                    return context.ExecutionMocks[req.GetType()].Invoke(req); - 3019336 - 4927337                 if (context.FakeMessageExecutors.ContainsKey(req.GetType()) - 4927338                    && context.FakeMessageExecutors[req.GetType()].CanExecute(req)) - 4909339                    return context.FakeMessageExecutors[req.GetType()].Execute(req, context); - 3019340 - 3037341                 if (req.GetType() == typeof(OrganizationRequest) - 3037342                    && context.GenericFakeMessageExecutors.ContainsKey(req.RequestName)) - 3031343                    return context.GenericFakeMessageExecutors[req.RequestName].Execute(req, context); - 3019344 - 3025345                throw PullRequestException.NotImplementedOrganizationRequest(req.GetType()); - 4671346            }; + 3069330        { + 3069331            OrganizationResponse response = null; + 3069332            Func<OrganizationRequest, OrganizationResponse> execute = (req) => + 4989333            { + 4989334                 if (context.ExecutionMocks.ContainsKey(req.GetType())) + 3081335                    return context.ExecutionMocks[req.GetType()].Invoke(req); + 3069336 + 4977337                 if (context.FakeMessageExecutors.ContainsKey(req.GetType()) + 4977338                    && context.FakeMessageExecutors[req.GetType()].CanExecute(req)) + 4959339                    return context.FakeMessageExecutors[req.GetType()].Execute(req, context); + 3069340 + 3087341                 if (req.GetType() == typeof(OrganizationRequest) + 3087342                    && context.GenericFakeMessageExecutors.ContainsKey(req.RequestName)) + 3081343                    return context.GenericFakeMessageExecutors[req.RequestName].Execute(req, context); + 3069344 + 3075345                throw PullRequestException.NotImplementedOrganizationRequest(req.GetType()); + 4721346            };  347 - 3019348            A.CallTo(() => fakedService.Execute(A<OrganizationRequest>._)) - 4939349                .Invokes((OrganizationRequest req) => response = execute(req)) - 4671350                .ReturnsLazily((OrganizationRequest req) => response); - 3019351        } + 3069348            A.CallTo(() => fakedService.Execute(A<OrganizationRequest>._)) + 4989349                .Invokes((OrganizationRequest req) => response = execute(req)) + 4721350                .ReturnsLazily((OrganizationRequest req) => response); + 3069351        }  352  353        public static void FakeAssociate(XrmFakedContext context, IOrganizationService fakedService) - 3019354        { - 3019355            A.CallTo(() => fakedService.Associate(A<string>._, A<Guid>._, A<Relationship>._, A<EntityReferenceCollection - 3019356                .Invokes((string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection entityC - 3115357                { - 3115358                     if (context.FakeMessageExecutors.ContainsKey(typeof(AssociateRequest))) - 3115359                    { - 3115360                        var request = new AssociateRequest() - 3115361                        { - 3115362                            Target = new EntityReference() { Id = entityId, LogicalName = entityName }, - 3115363                            Relationship = relationship, - 3115364                            RelatedEntities = entityCollection - 3115365                        }; - 3115366                        context.FakeMessageExecutors[typeof(AssociateRequest)].Execute(request, context); - 3115367                    } - 3019368                    else - 3019369                        throw PullRequestException.NotImplementedOrganizationRequest(typeof(AssociateRequest)); - 3115370                }); - 3019371        } + 3069354        { + 3069355            A.CallTo(() => fakedService.Associate(A<string>._, A<Guid>._, A<Relationship>._, A<EntityReferenceCollection + 3069356                .Invokes((string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection entityC + 3177357                { + 3177358                     if (context.FakeMessageExecutors.ContainsKey(typeof(AssociateRequest))) + 3177359                    { + 3177360                        var request = new AssociateRequest() + 3177361                        { + 3177362                            Target = new EntityReference() { Id = entityId, LogicalName = entityName }, + 3177363                            Relationship = relationship, + 3177364                            RelatedEntities = entityCollection + 3177365                        }; + 3177366                        context.FakeMessageExecutors[typeof(AssociateRequest)].Execute(request, context); + 3177367                    } + 3069368                    else + 3069369                        throw PullRequestException.NotImplementedOrganizationRequest(typeof(AssociateRequest)); + 3177370                }); + 3069371        }  372  373        public static void FakeDisassociate(XrmFakedContext context, IOrganizationService fakedService) - 3019374        { - 3019375            A.CallTo(() => fakedService.Disassociate(A<string>._, A<Guid>._, A<Relationship>._, A<EntityReferenceCollect - 3019376                .Invokes((string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection entityC - 3037377                { - 3037378                     if (context.FakeMessageExecutors.ContainsKey(typeof(DisassociateRequest))) - 3037379                    { - 3037380                        var request = new DisassociateRequest() - 3037381                        { - 3037382                            Target = new EntityReference() { Id = entityId, LogicalName = entityName }, - 3037383                            Relationship = relationship, - 3037384                            RelatedEntities = entityCollection - 3037385                        }; - 3037386                        context.FakeMessageExecutors[typeof(DisassociateRequest)].Execute(request, context); - 3037387                    } - 3019388                    else - 3019389                        throw PullRequestException.NotImplementedOrganizationRequest(typeof(DisassociateRequest)); - 3037390                }); - 3019391        } + 3069374        { + 3069375            A.CallTo(() => fakedService.Disassociate(A<string>._, A<Guid>._, A<Relationship>._, A<EntityReferenceCollect + 3069376                .Invokes((string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection entityC + 3087377                { + 3087378                     if (context.FakeMessageExecutors.ContainsKey(typeof(DisassociateRequest))) + 3087379                    { + 3087380                        var request = new DisassociateRequest() + 3087381                        { + 3087382                            Target = new EntityReference() { Id = entityId, LogicalName = entityName }, + 3087383                            Relationship = relationship, + 3087384                            RelatedEntities = entityCollection + 3087385                        }; + 3087386                        context.FakeMessageExecutors[typeof(DisassociateRequest)].Execute(request, context); + 3087387                    } + 3069388                    else + 3069389                        throw PullRequestException.NotImplementedOrganizationRequest(typeof(DisassociateRequest)); + 3087390                }); + 3069391        }  392  393        public static void FakeRetrieveMultiple(XrmFakedContext context, IOrganizationService fakedService) - 3019394        { - 3019395            EntityCollection entities = null; - 3019396            Func<QueryBase, EntityCollection> retriveMultiple = (QueryBase req) => - 4449397            { - 4449398                var request = new RetrieveMultipleRequest { Query = req }; - 3019399 - 4449400                var executor = new RetrieveMultipleRequestExecutor(); - 4449401                var response = executor.Execute(request, context) as RetrieveMultipleResponse; - 3019402 - 4417403                return response.EntityCollection; - 4417404            }; + 3069394        { + 3069395            EntityCollection entities = null; + 3069396            Func<QueryBase, EntityCollection> retriveMultiple = (QueryBase req) => + 4537397            { + 4537398                var request = new RetrieveMultipleRequest { Query = req }; + 3069399 + 4537400                var executor = new RetrieveMultipleRequestExecutor(); + 4537401                var response = executor.Execute(request, context) as RetrieveMultipleResponse; + 3069402 + 4505403                return response.EntityCollection; + 4505404            };  405  406            //refactored from RetrieveMultipleExecutor - 3019407            A.CallTo(() => fakedService.RetrieveMultiple(A<QueryBase>._)) - 4449408                .Invokes((QueryBase req) => entities = retriveMultiple(req)) - 4417409                .ReturnsLazily((QueryBase req) => entities); - 3019410        } + 3069407            A.CallTo(() => fakedService.RetrieveMultiple(A<QueryBase>._)) + 4537408                .Invokes((QueryBase req) => entities = retriveMultiple(req)) + 4505409                .ReturnsLazily((QueryBase req) => entities); + 3069410        }  411  412        public IServiceEndpointNotificationService GetFakedServiceEndpointNotificationService()  12413        { @@ -1937,61 +1943,61 @@

D:\Git\fake-x  6{  7    public partial class XrmFakedContext : IXrmContext  8    { - 40009        public TimeZoneInfo SystemTimeZone { get; set; } + 40509        public TimeZoneInfo SystemTimeZone { get; set; }  10 - 2714611        public Dictionary<string, Dictionary<string, DateTimeAttributeBehavior>> DateBehaviour { get; set; } + 2725211        public Dictionary<string, Dictionary<string, DateTimeAttributeBehavior>> DateBehaviour { get; set; }  12  13        private static Dictionary<string, Dictionary<string, DateTimeAttributeBehavior>> DefaultDateBehaviour() - 400014        { + 405014        {  15#if FAKE_XRM_EASY || FAKE_XRM_EASY_2013 - 129016            return new Dictionary<string, Dictionary<string, DateTimeAttributeBehavior>>(); + 130416            return new Dictionary<string, Dictionary<string, DateTimeAttributeBehavior>>();  17#else - 271018            return new Dictionary<string, Dictionary<string, DateTimeAttributeBehavior>> - 271019            { - 271020                { - 271021                    "contact", new Dictionary<string, DateTimeAttributeBehavior> - 271022                    { - 271023                        { "anniversary", DateTimeAttributeBehavior.DateOnly }, - 271024                        { "birthdate", DateTimeAttributeBehavior.DateOnly } - 271025                    } - 271026                }, - 271027                { - 271028                    "invoice", new Dictionary<string, DateTimeAttributeBehavior> - 271029                    { - 271030                        { "duedate", DateTimeAttributeBehavior.DateOnly } - 271031                    } - 271032                }, - 271033                { - 271034                    "lead", new Dictionary<string, DateTimeAttributeBehavior> - 271035                    { - 271036                        { "estimatedclosedate", DateTimeAttributeBehavior.DateOnly } - 271037                    } - 271038                }, - 271039                { - 271040                    "opportunity", new Dictionary<string, DateTimeAttributeBehavior> - 271041                    { - 271042                        { "actualclosedate", DateTimeAttributeBehavior.DateOnly }, - 271043                        { "estimatedclosedate", DateTimeAttributeBehavior.DateOnly }, - 271044                        { "finaldecisiondate", DateTimeAttributeBehavior.DateOnly } - 271045                    } - 271046                }, - 271047                { - 271048                    "product", new Dictionary<string, DateTimeAttributeBehavior> - 271049                    { - 271050                        { "validfromdate", DateTimeAttributeBehavior.DateOnly }, - 271051                        { "validtodate", DateTimeAttributeBehavior.DateOnly } - 271052                    } - 271053                }, - 271054                { - 271055                    "quote", new Dictionary<string, DateTimeAttributeBehavior> - 271056                    { - 271057                        { "closedon", DateTimeAttributeBehavior.DateOnly }, - 271058                        { "dueby", DateTimeAttributeBehavior.DateOnly } - 271059                    } - 271060                } - 271061            }; + 274618            return new Dictionary<string, Dictionary<string, DateTimeAttributeBehavior>> + 274619            { + 274620                { + 274621                    "contact", new Dictionary<string, DateTimeAttributeBehavior> + 274622                    { + 274623                        { "anniversary", DateTimeAttributeBehavior.DateOnly }, + 274624                        { "birthdate", DateTimeAttributeBehavior.DateOnly } + 274625                    } + 274626                }, + 274627                { + 274628                    "invoice", new Dictionary<string, DateTimeAttributeBehavior> + 274629                    { + 274630                        { "duedate", DateTimeAttributeBehavior.DateOnly } + 274631                    } + 274632                }, + 274633                { + 274634                    "lead", new Dictionary<string, DateTimeAttributeBehavior> + 274635                    { + 274636                        { "estimatedclosedate", DateTimeAttributeBehavior.DateOnly } + 274637                    } + 274638                }, + 274639                { + 274640                    "opportunity", new Dictionary<string, DateTimeAttributeBehavior> + 274641                    { + 274642                        { "actualclosedate", DateTimeAttributeBehavior.DateOnly }, + 274643                        { "estimatedclosedate", DateTimeAttributeBehavior.DateOnly }, + 274644                        { "finaldecisiondate", DateTimeAttributeBehavior.DateOnly } + 274645                    } + 274646                }, + 274647                { + 274648                    "product", new Dictionary<string, DateTimeAttributeBehavior> + 274649                    { + 274650                        { "validfromdate", DateTimeAttributeBehavior.DateOnly }, + 274651                        { "validtodate", DateTimeAttributeBehavior.DateOnly } + 274652                    } + 274653                }, + 274654                { + 274655                    "quote", new Dictionary<string, DateTimeAttributeBehavior> + 274656                    { + 274657                        { "closedon", DateTimeAttributeBehavior.DateOnly }, + 274658                        { "dueby", DateTimeAttributeBehavior.DateOnly } + 274659                    } + 274660                } + 274661            };  62#endif - 400063        } + 405063        }  64    }  65} @@ -2017,46 +2023,46 @@

D:\Git\fake-x  15        /// <summary>  16        /// Stores some minimal metadata info if dynamic entities are used and no injected metadata was used  17        /// </summary> - 249216618        protected internal Dictionary<string, Dictionary<string, string>> AttributeMetadataNames { get; set; } + 249993618        protected internal Dictionary<string, Dictionary<string, string>> AttributeMetadataNames { get; set; }  19  20        /// <summary>  21        /// Stores fake global option set metadata  22        /// </summary> - 417423        public Dictionary<string, OptionSetMetadata> OptionSetValuesMetadata { get; set; } + 422423        public Dictionary<string, OptionSetMetadata> OptionSetValuesMetadata { get; set; }  24  25        /// <summary>  26        /// Stores fake global status values metadata  27        /// </summary> - 403028        public Dictionary<string, StatusAttributeMetadata> StatusAttributeMetadata { get; set; } + 408028        public Dictionary<string, StatusAttributeMetadata> StatusAttributeMetadata { get; set; }  29  30        /// <summary>  31        /// Stores fake entity metadata  32        /// </summary> - 17902133        protected internal Dictionary<string, EntityMetadata> EntityMetadata { get; set; } + 17949733        protected internal Dictionary<string, EntityMetadata> EntityMetadata { get; set; }  34  35  36        public void InitializeMetadata(IEnumerable<EntityMetadata> entityMetadataList) - 15237        { - 15238             if (entityMetadataList == null) + 16437        { + 16438             if (entityMetadataList == null)  639            {  640                throw new Exception("Entity metadata parameter can not be null");  41            }  42  43            //  this.EntityMetadata = new Dictionary<string, EntityMetadata>(); - 655844            foreach (var eMetadata in entityMetadataList) - 306945            { - 306946                 if (string.IsNullOrWhiteSpace(eMetadata.LogicalName)) + 661844            foreach (var eMetadata in entityMetadataList) + 308145            { + 308146                 if (string.IsNullOrWhiteSpace(eMetadata.LogicalName))  1247                {  1248                    throw new Exception("An entity metadata record must have a LogicalName property.");  49                }  50 - 305751                 if (EntityMetadata.ContainsKey(eMetadata.LogicalName)) + 306951                 if (EntityMetadata.ContainsKey(eMetadata.LogicalName))  652                {  653                    throw new Exception("An entity metadata record with the same logical name was previously added. ");  54                } - 305155                EntityMetadata.Add(eMetadata.LogicalName, eMetadata.Copy()); - 305156            } - 12857        } + 306355                EntityMetadata.Add(eMetadata.LogicalName, eMetadata.Copy()); + 306356            } + 14057        }  58  59        public void InitializeMetadata(EntityMetadata entityMetadata)  9860        { @@ -2073,51 +2079,52 @@

D:\Git\fake-x  1271        }  72  73        public IQueryable<EntityMetadata> CreateMetadataQuery() - 12074        { - 12075            return this.EntityMetadata.Values - 314576                    .Select(em => em.Copy()) - 12077                    .ToList() - 12078                    .AsQueryable(); - 12079        } + 3074        { + 3075            return this.EntityMetadata.Values + 151976                    .Select(em => em.Copy()) + 3077                    .ToList() + 3078                    .AsQueryable(); + 3079        }  80  81        public EntityMetadata GetEntityMetadataByName(string sLogicalName)  9082        { - 9083            return CreateMetadataQuery() - 9084                .Where(em => em.LogicalName.Equals(sLogicalName)) - 9085                .FirstOrDefault(); - 9086        }8788        public void SetEntityMetadata(EntityMetadata em) - 3089        { - 3090             if (this.EntityMetadata.ContainsKey(em.LogicalName)) - 3091                this.EntityMetadata[em.LogicalName] = em.Copy();92            else - 093                this.EntityMetadata.Add(em.LogicalName, em.Copy()); - 3094        }9596        public AttributeMetadata GetAttributeMetadataFor(string sEntityName, string sAttributeName, Type attributeType) - 097        { - 098             if (EntityMetadata.ContainsKey(sEntityName)) - 099            { - 0100                var entityMetadata = GetEntityMetadataByName(sEntityName); - 0101                var attribute = entityMetadata.Attributes - 0102                                .Where(a => a.LogicalName.Equals(sAttributeName)) - 0103                                .FirstOrDefault();104 - 0105                 if (attribute != null) - 0106                    return attribute; - 0107            }108 - 0109             if (attributeType == typeof(string)) - 0110            { - 0111                return new StringAttributeMetadata(sAttributeName);112            }113            //Default - 0114            return new StringAttributeMetadata(sAttributeName); - 0115        }116117    }118} + 9083             if (EntityMetadata.ContainsKey(sLogicalName)) + 7884                return EntityMetadata[sLogicalName].Copy();85 + 1286            return null; + 9087        }8889        public void SetEntityMetadata(EntityMetadata em) + 3090        { + 3091             if (this.EntityMetadata.ContainsKey(em.LogicalName)) + 3092                this.EntityMetadata[em.LogicalName] = em.Copy();93            else + 094                this.EntityMetadata.Add(em.LogicalName, em.Copy()); + 3095        }9697        public AttributeMetadata GetAttributeMetadataFor(string sEntityName, string sAttributeName, Type attributeType) + 098        { + 099             if (EntityMetadata.ContainsKey(sEntityName)) + 0100            { + 0101                var entityMetadata = GetEntityMetadataByName(sEntityName); + 0102                var attribute = entityMetadata.Attributes + 0103                                .Where(a => a.LogicalName.Equals(sAttributeName)) + 0104                                .FirstOrDefault();105 + 0106                 if (attribute != null) + 0107                    return attribute; + 0108            }109 + 0110             if (attributeType == typeof(string)) + 0111            { + 0112                return new StringAttributeMetadata(sAttributeName);113            }114            //Default + 0115            return new StringAttributeMetadata(sAttributeName); + 0116        }117118    }119}

D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedContext.Pipeline.cs

@@ -2135,7 +2142,7 @@

D:\Git\fake-x  9{  10    public partial class XrmFakedContext : IXrmContext  11    { - 613412        public bool UsePipelineSimulation { get; set; } + 619612        public bool UsePipelineSimulation { get; set; }  13  14        /// <summary>  15        /// Registers the <typeparamref name="TPlugin"/> as a SDK Message Processing Step for the Entity <typeparamref n @@ -2777,12 +2784,12 @@

D:\Git\fake-xr  21    public partial class XrmFakedContext : IXrmContext  22    {  23        protected internal Type FindReflectedType(string logicalName) - 2823024        { - 2823025            var types = - 8063826                ProxyTypesAssemblies.Select(a => FindReflectedType(logicalName, a)) - 8063827                                    .Where(t => t != null); + 2843624        { + 2843625            var types = + 8103626                ProxyTypesAssemblies.Select(a => FindReflectedType(logicalName, a)) + 8103627                                    .Where(t => t != null);  28 - 2823029             if (types.Count() > 1) + 2843629             if (types.Count() > 1)  030            {  031                var errorMsg = $"Type { logicalName } is defined in multiple assemblies: ";  032                foreach (var type in types) @@ -2796,8 +2803,8 @@

D:\Git\fake-xr  040                throw new InvalidOperationException(errorMsg);  41            }  42 - 2823043            return types.SingleOrDefault(); - 2823044        } + 2843643            return types.SingleOrDefault(); + 2843644        }  45  46        /// <summary>  47        /// Finds reflected type for given entity from given assembly. @@ -2816,10 +2823,10 @@

D:\Git\fake-xr  60        /// </returns>  61        private static Type FindReflectedType(string logicalName,  62                                              Assembly assembly) - 5240863        { + 5260063        {  64            try - 5240865            { - 5240866                 if (assembly == null) + 5260065            { + 5260066                 if (assembly == null)  067                {  068                    throw new ArgumentNullException(nameof(assembly));  69                } @@ -2831,13 +2838,13 @@

D:\Git\fake-xr  75                        .FirstOrDefault(t => t.GetCustomAttributes<EntityLogicalNameAttribute>(true).First().LogicalName  76  77                */ - 5240878                var subClassType = assembly.GetTypes() - 697790279                        .Where(t => typeof(Entity).IsAssignableFrom(t)) - 424377480                        .Where(t => t.GetCustomAttributes(typeof(EntityLogicalNameAttribute), true).Length > 0) - 424377481                        .Where(t => ((EntityLogicalNameAttribute)t.GetCustomAttributes(typeof(EntityLogicalNameAttribute - 5240882                        .FirstOrDefault(); + 5260078                var subClassType = assembly.GetTypes() + 698774279                        .Where(t => typeof(Entity).IsAssignableFrom(t)) + 424783080                        .Where(t => t.GetCustomAttributes(typeof(EntityLogicalNameAttribute), true).Length > 0) + 424783081                        .Where(t => ((EntityLogicalNameAttribute)t.GetCustomAttributes(typeof(EntityLogicalNameAttribute + 5260082                        .FirstOrDefault();  83 - 5240884                return subClassType; + 5260084                return subClassType;  85            }  086            catch (ReflectionTypeLoadException exception)  087            { @@ -2851,7 +2858,7 @@

D:\Git\fake-xr  95  096                throw new Exception("XrmFakedContext.FindReflectedType: " + s);  97            } - 5240898        } + 5260098        }  99  100        protected internal Type FindAttributeTypeInInjectedMetadata(string sEntityName, string sAttributeName)  14101        { @@ -2934,10 +2941,10 @@

D:\Git\fake-xr  178  14179        }  180        protected internal Type FindReflectedAttributeType(Type earlyBoundType, string sEntityName, string attributeName - 2830181        { + 2860181        {  182            //Get that type properties - 2830183            var attributeInfo = GetEarlyBoundTypeAttribute(earlyBoundType, attributeName); - 2830184             if (attributeInfo == null && attributeName.EndsWith("name")) + 2860183            var attributeInfo = GetEarlyBoundTypeAttribute(earlyBoundType, attributeName); + 2860184             if (attributeInfo == null && attributeName.EndsWith("name"))  6185            {  186                // Special case for referencing the name of a EntityReference  6187                attributeName = attributeName.Substring(0, attributeName.Length - 4); @@ -2950,7 +2957,7 @@

D:\Git\fake-xr  0194                }  6195            }  196 - 2830197             if (attributeInfo == null || attributeInfo.PropertyType.FullName == null) + 2860197             if (attributeInfo == null || attributeInfo.PropertyType.FullName == null)  14198            {  199                //Try with metadata  14200                var injectedType = FindAttributeTypeInInjectedMetadata(sEntityName, attributeName); @@ -2963,50 +2970,50 @@

D:\Git\fake-xr  8207                return injectedType;  208            }  209 - 2816210             if (attributeInfo.PropertyType.FullName.EndsWith("Enum") || attributeInfo.PropertyType.BaseType.FullName.End + 2846210             if (attributeInfo.PropertyType.FullName.EndsWith("Enum") || attributeInfo.PropertyType.BaseType.FullName.End  0211            {  0212                return typeof(int);  213            }  214 - 2816215             if (!attributeInfo.PropertyType.FullName.StartsWith("System.")) - 867216            { + 2846215             if (!attributeInfo.PropertyType.FullName.StartsWith("System.")) + 879216            {  217                try - 867218                { - 867219                    var instance = Activator.CreateInstance(attributeInfo.PropertyType); - 867220                     if (instance is Entity) + 879218                { + 879219                    var instance = Activator.CreateInstance(attributeInfo.PropertyType); + 879220                     if (instance is Entity)  0221                    {  0222                        return typeof(EntityReference);  223                    } - 867224                } + 879224                }  0225                catch  0226                {  227                    // ignored  0228                } - 867229            } + 879229            }  230#if FAKE_XRM_EASY_2015 || FAKE_XRM_EASY_2016 || FAKE_XRM_EASY_365 || FAKE_XRM_EASY_9 - 1304231             else if (attributeInfo.PropertyType.FullName.StartsWith("System.Nullable")) - 646232            { - 646233                return attributeInfo.PropertyType.GenericTypeArguments[0]; + 1316231             else if (attributeInfo.PropertyType.FullName.StartsWith("System.Nullable")) + 684232            { + 684233                return attributeInfo.PropertyType.GenericTypeArguments[0];  234            }  235#endif  236 - 2170237            return attributeInfo.PropertyType; - 2824238        } + 2162237            return attributeInfo.PropertyType; + 2854238        }  239  240        private static PropertyInfo GetEarlyBoundTypeAttribute(Type earlyBoundType, string attributeName) - 3221241        { - 3221242            var attributeInfo = earlyBoundType.GetProperties() - 198711243                .Where(pi => pi.GetCustomAttributes(typeof(AttributeLogicalNameAttribute), true).Length > 0) - 192676244                .Where(pi => (pi.GetCustomAttributes(typeof(AttributeLogicalNameAttribute), true)[0] as AttributeLogical - 3221245                .FirstOrDefault(); + 3251241        { + 3251242            var attributeInfo = earlyBoundType.GetProperties() + 202887243                .Where(pi => pi.GetCustomAttributes(typeof(AttributeLogicalNameAttribute), true).Length > 0) + 196481244                .Where(pi => (pi.GetCustomAttributes(typeof(AttributeLogicalNameAttribute), true)[0] as AttributeLogical + 3251245                .FirstOrDefault();  246 - 3221247            return attributeInfo; - 3221248        } + 3251247            return attributeInfo; + 3251248        }  249  250        public IQueryable<Entity> CreateQuery(string entityLogicalName) - 1474251        { - 1474252            return this.CreateQuery<Entity>(entityLogicalName); - 1468253        } + 1498251        { + 1498252            return this.CreateQuery<Entity>(entityLogicalName); + 1492253        }  254  255        public IQueryable<T> CreateQuery<T>()  256            where T : Entity @@ -3035,32 +3042,32 @@

D:\Git\fake-xr  279  280        protected IQueryable<T> CreateQuery<T>(string entityLogicalName)  281            where T : Entity - 5707282        { - 5707283            var subClassType = FindReflectedType(entityLogicalName); - 5707284             if (subClassType == null && !(typeof(T) == typeof(Entity)) || (typeof(T) == typeof(Entity) && string.IsNullO + 5807282        { + 5807283            var subClassType = FindReflectedType(entityLogicalName); + 5807284             if (subClassType == null && !(typeof(T) == typeof(Entity)) || (typeof(T) == typeof(Entity) && string.IsNullO  6285            {  6286                throw new Exception($"The type {entityLogicalName} was not found");  287            }  288 - 5701289            var lst = new List<T>(); - 5701290             if (!Data.ContainsKey(entityLogicalName)) + 5801289            var lst = new List<T>(); + 5801290             if (!Data.ContainsKey(entityLogicalName))  452291            {  452292                return lst.AsQueryable(); //Empty list  293            }  294 - 143671295            foreach (var e in Data[entityLogicalName].Values) - 63962296            { - 63962297                 if (subClassType != null) - 23277298                { - 23277299                    var cloned = e.Clone(subClassType); - 23277300                    lst.Add((T)cloned); - 23277301                } + 144195295            foreach (var e in Data[entityLogicalName].Values) + 64074296            { + 64074297                 if (subClassType != null) + 23289298                { + 23289299                    var cloned = e.Clone(subClassType); + 23289300                    lst.Add((T)cloned); + 23289301                }  302                else - 40685303                    lst.Add((T)e.Clone()); - 63962304            } + 40785303                    lst.Add((T)e.Clone()); + 64074304            }  305 - 5249306            return lst.AsQueryable(); - 5701307        } + 5349306            return lst.AsQueryable(); + 5801307        }  308  309        public IQueryable<Entity> CreateQueryFromEntityName(string entityName)  0310        { @@ -3068,26 +3075,26 @@

D:\Git\fake-xr  0312        }  313  314        public static IQueryable<Entity> TranslateLinkedEntityToLinq(XrmFakedContext context, LinkEntity le, IQueryable< - 1555315        { - 1555316             if (!string.IsNullOrEmpty(le.EntityAlias)) - 1555317            { - 1555318                 if (!Regex.IsMatch(le.EntityAlias, "^[A-Za-z_]\\w*$", RegexOptions.ECMAScript)) + 1593315        { + 1593316             if (!string.IsNullOrEmpty(le.EntityAlias)) + 1593317            { + 1593318                 if (!Regex.IsMatch(le.EntityAlias, "^[A-Za-z_](\\w|\\.)*$", RegexOptions.ECMAScript))  0319                {  0320                    throw new FaultException(new FaultReason($"Invalid character specified for alias: {le.EntityAlias}.   321                } - 1555322            } + 1593322            }  323 - 1555324            var leAlias = string.IsNullOrWhiteSpace(le.EntityAlias) ? le.LinkToEntityName : le.EntityAlias; - 1555325             context.EnsureEntityNameExistsInMetadata(le.LinkFromEntityName != linkFromAlias ? le.LinkFromEntityName : li - 1555326            context.EnsureEntityNameExistsInMetadata(le.LinkToEntityName); + 1593324            var leAlias = string.IsNullOrWhiteSpace(le.EntityAlias) ? le.LinkToEntityName : le.EntityAlias; + 1593325             context.EnsureEntityNameExistsInMetadata(le.LinkFromEntityName != linkFromAlias ? le.LinkFromEntityName : li + 1593326            context.EnsureEntityNameExistsInMetadata(le.LinkToEntityName);  327 - 1555328             if (!context.AttributeExistsInMetadata(le.LinkToEntityName, le.LinkToAttributeName)) + 1593328             if (!context.AttributeExistsInMetadata(le.LinkToEntityName, le.LinkToAttributeName))  12329            {  12330                OrganizationServiceFaultQueryBuilderNoAttributeException.Throw(le.LinkToAttributeName);  0331            }  332 - 1543333            IQueryable<Entity> inner = null; - 1543334             if (le.JoinOperator == JoinOperator.LeftOuter) + 1581333            IQueryable<Entity> inner = null; + 1581334             if (le.JoinOperator == JoinOperator.LeftOuter)  362335            {  336                //inner = context.CreateQuery<Entity>(le.LinkToEntityName);  337 @@ -3105,35 +3112,35 @@

D:\Git\fake-xr  349  362350            }  351            else - 1181352            { + 1219352            {  353                //Filters are applied after joins - 1181354                inner = context.CreateQuery<Entity>(le.LinkToEntityName); - 1181355            } + 1219354                inner = context.CreateQuery<Entity>(le.LinkToEntityName); + 1219355            }  356  357            //if (!le.Columns.AllColumns && le.Columns.Columns.Count == 0)  358            //{  359            //    le.Columns.AllColumns = true;   //Add all columns in the joined entity, otherwise we can't filter by r  360            //}  361 - 1543362             if (string.IsNullOrWhiteSpace(linkFromAlias)) - 1429363            { - 1429364                linkFromAlias = le.LinkFromAttributeName; - 1429365            } + 1581362             if (string.IsNullOrWhiteSpace(linkFromAlias)) + 1467363            { + 1467364                linkFromAlias = le.LinkFromAttributeName; + 1467365            }  366            else  114367            {  114368                linkFromAlias += "." + le.LinkFromAttributeName;  114369            }  370 - 1543371             switch (le.JoinOperator) + 1581371             switch (le.JoinOperator)  372            {  373                case JoinOperator.Inner:  374                case JoinOperator.Natural: - 1181375                    query = query.Join(inner, - 1181376                                    outerKey => outerKey.KeySelector(linkFromAlias, context), - 1181377                                    innerKey => innerKey.KeySelector(le.LinkToAttributeName, context), - 1181378                                    (outerEl, innerEl) => outerEl.Clone(outerEl.GetType(), context).JoinAttributes(inner + 1219375                    query = query.Join(inner, + 1219376                                    outerKey => outerKey.KeySelector(linkFromAlias, context), + 1219377                                    innerKey => innerKey.KeySelector(le.LinkToAttributeName, context), + 1219378                                    (outerEl, innerEl) => outerEl.Clone(outerEl.GetType(), context).JoinAttributes(inner  379 - 1181380                    break; + 1219380                    break;  381                case JoinOperator.LeftOuter:  362382                    query = query.GroupJoin(inner,  362383                                    outerKey => outerKey.KeySelector(linkFromAlias, context), @@ -3151,7 +3158,7 @@

D:\Git\fake-xr  395            }  396  397            // Process nested linked entities recursively - 4857398            foreach (var nestedLinkedEntity in le.LinkEntities) + 4971398            foreach (var nestedLinkedEntity in le.LinkEntities)  114399            {  114400                 if (string.IsNullOrWhiteSpace(le.EntityAlias))  0401                { @@ -3166,40 +3173,40 @@

D:\Git\fake-xr  114410                query = TranslateLinkedEntityToLinq(context, nestedLinkedEntity, query, le.Columns, linkedEntities, le.E  114411            }  412 - 1543413            return query; - 1543414        } + 1581413            return query; + 1581414        }  415  416        private static string EnsureUniqueLinkedEntityAlias(IDictionary<string, int> linkedEntities, string entityName) - 346417        { - 346418             if (linkedEntities.ContainsKey(entityName)) + 368417        { + 368418             if (linkedEntities.ContainsKey(entityName))  30419            {  30420                linkedEntities[entityName]++;  30421            }  422            else - 316423            { - 316424                linkedEntities[entityName] = 1; - 316425            } + 338423            { + 338424                linkedEntities[entityName] = 1; + 338425            }  426 - 346427            return $"{entityName}{linkedEntities[entityName]}"; - 346428        } + 368427            return $"{entityName}{linkedEntities[entityName]}"; + 368428        }  429  430  431        protected static XElement RetrieveFetchXmlNode(XDocument xlDoc, string sName) - 1282432        { - 4104433            return xlDoc.Descendants().Where(e => e.Name.LocalName.Equals(sName)).FirstOrDefault(); - 1282434        } + 1292432        { + 4134433            return xlDoc.Descendants().Where(e => e.Name.LocalName.Equals(sName)).FirstOrDefault(); + 1292434        }  435  436        public static XDocument ParseFetchXml(string fetchXml) - 1042437        { + 1052437        {  438            try - 1042439            { - 1042440                return XDocument.Parse(fetchXml); + 1052439            { + 1052440                return XDocument.Parse(fetchXml);  441            }  6442            catch (Exception ex)  6443            {  6444                throw new Exception(string.Format("FetchXml must be a valid XML document: {0}", ex.ToString()));  445            } - 1036446        } + 1046446        }  447  448        public static QueryExpression TranslateFetchXmlToQueryExpression(XrmFakedContext context, string fetchXml)  477449        { @@ -3207,1605 +3214,1698 @@

D:\Git\fake-xr  411451        }  452  453        public static QueryExpression TranslateFetchXmlDocumentToQueryExpression(XrmFakedContext context, XDocument xlDo - 1036454        { + 1046454        {  455            //Validate nodes - 7311456             if (!xlDoc.Descendants().All(el => el.IsFetchXmlNodeValid())) + 7381456             if (!xlDoc.Descendants().All(el => el.IsFetchXmlNodeValid()))  36457                throw new Exception("At least some node is not valid");  458  459            //Root node - 994460             if (!xlDoc.Root.Name.LocalName.Equals("fetch")) + 1004460             if (!xlDoc.Root.Name.LocalName.Equals("fetch"))  0461            {  0462                throw new Exception("Root node must be fetch");  463            }  464 - 994465            var entityNode = RetrieveFetchXmlNode(xlDoc, "entity"); - 994466            var query = new QueryExpression(entityNode.GetAttribute("name").Value); + 1004465            var entityNode = RetrieveFetchXmlNode(xlDoc, "entity"); + 1004466            var query = new QueryExpression(entityNode.GetAttribute("name").Value);  467 - 994468            query.ColumnSet = xlDoc.ToColumnSet(); + 1004468            query.ColumnSet = xlDoc.ToColumnSet();  469  470            // Ordering is done after grouping/aggregation - 994471             if (!xlDoc.IsAggregateFetchXml()) - 850472            { - 850473                var orders = xlDoc.ToOrderExpressionList(); - 2838474                foreach (var order in orders) + 1004471             if (!xlDoc.IsAggregateFetchXml()) + 860472            { + 860473                var orders = xlDoc.ToOrderExpressionList(); + 2868474                foreach (var order in orders)  144475                {  144476                    query.AddOrder(order.AttributeName, order.OrderType);  144477                } - 850478            } + 860478            }  479 - 994480            query.Criteria = xlDoc.ToCriteria(context); + 1004480            query.Criteria = xlDoc.ToCriteria(context);  481 - 964482            query.TopCount = xlDoc.ToTopCount(); + 974482            query.TopCount = xlDoc.ToTopCount();  483 - 964484             query.PageInfo.Count = xlDoc.ToCount() ?? 0; - 958485             query.PageInfo.PageNumber = xlDoc.ToPageNumber() ?? 1; - 958486            query.PageInfo.ReturnTotalRecordCount = xlDoc.ToReturnTotalRecordCount(); + 974484             query.PageInfo.Count = xlDoc.ToCount() ?? 0; + 968485             query.PageInfo.PageNumber = xlDoc.ToPageNumber() ?? 1; + 968486            query.PageInfo.ReturnTotalRecordCount = xlDoc.ToReturnTotalRecordCount();  487 - 958488            var linkedEntities = xlDoc.ToLinkEntities(context); - 3182489            foreach (var le in linkedEntities) - 154490            { - 154491                query.LinkEntities.Add(le); - 154492            } + 968488            var linkedEntities = xlDoc.ToLinkEntities(context); + 3232489            foreach (var le in linkedEntities) + 164490            { + 164491                query.LinkEntities.Add(le); + 164492            }  493 - 958494            return query; - 958495        } + 968494            return query; + 968495        }  496  497        public static IQueryable<Entity> TranslateQueryExpressionToLinq(XrmFakedContext context, QueryExpression qe) - 2797498        { - 2803499             if (qe == null) return null; + 2835498        { + 2841499             if (qe == null) return null;  500  501            //Start form the root entity and build a LINQ query to execute the query against the In-Memory context: - 2791502            context.EnsureEntityNameExistsInMetadata(qe.EntityName); + 2829502            context.EnsureEntityNameExistsInMetadata(qe.EntityName);  503 - 2791504            IQueryable<Entity> query = null; + 2829504            IQueryable<Entity> query = null;  505 - 2791506            query = context.CreateQuery<Entity>(qe.EntityName); + 2829506            query = context.CreateQuery<Entity>(qe.EntityName);  507 - 2791508            var linkedEntities = new Dictionary<string, int>(); + 2829508            var linkedEntities = new Dictionary<string, int>();  509510            // Add as many Joins as linked entities - 11243511            foreach (var le in qe.LinkEntities) - 1441512            { - 1441513                 if (string.IsNullOrWhiteSpace(le.EntityAlias)) - 292514                { - 292515                    le.EntityAlias = EnsureUniqueLinkedEntityAlias(linkedEntities, le.LinkToEntityName); - 292516                }517 - 1441518                query = TranslateLinkedEntityToLinq(context, le, query, qe.ColumnSet, linkedEntities); - 1429519            }520521            // Compose the expression tree that represents the parameter to the predicate. - 2779522            ParameterExpression entity = Expression.Parameter(typeof(Entity)); - 2779523            var expTreeBody = TranslateQueryExpressionFiltersToExpression(context, qe, entity); - 2746524            Expression<Func<Entity, bool>> lambda = Expression.Lambda<Func<Entity, bool>>(expTreeBody, entity); - 2746525            query = query.Where(lambda);526527            //Sort results - 2746528             if (qe.Orders != null) - 2746529            { - 2746530                 if (qe.Orders.Count > 0) - 420531                { - 420532                    IOrderedQueryable<Entity> orderedQuery = null;533 - 420534                    var order = qe.Orders[0]; - 420535                     if (order.OrderType == OrderType.Ascending) - 384536                        orderedQuery = query.OrderBy(e => e.Attributes.ContainsKey(order.AttributeName) ? e[order.Attrib537                    else - 36538                        orderedQuery = query.OrderByDescending(e => e.Attributes.ContainsKey(order.AttributeName) ? e[or539540                    //Subsequent orders should use ThenBy and ThenByDescending - 888541                     for (var i = 1; i < qe.Orders.Count; i++) - 24542                    { - 24543                        var thenOrder = qe.Orders[i]; - 24544                         if (thenOrder.OrderType == OrderType.Ascending) - 12545                            orderedQuery = orderedQuery.ThenBy(e => e.Attributes.ContainsKey(thenOrder.AttributeName) ? 546                        else - 12547                            orderedQuery = orderedQuery.ThenByDescending(e => e[thenOrder.AttributeName], new XrmOrderBy - 24548                    }549 - 420550                    query = orderedQuery; - 420551                } - 2746552            }510#if  !FAKE_XRM_EASY + 2383511            ValidateAliases(qe, context);512#endif513514            // Add as many Joins as linked entities + 11433515            foreach (var le in qe.LinkEntities) + 1479516            { + 1479517                 if (string.IsNullOrWhiteSpace(le.EntityAlias)) + 314518                { + 314519                    le.EntityAlias = EnsureUniqueLinkedEntityAlias(linkedEntities, le.LinkToEntityName); + 314520                }521 + 1479522                query = TranslateLinkedEntityToLinq(context, le, query, qe.ColumnSet, linkedEntities); + 1467523            }524525            // Compose the expression tree that represents the parameter to the predicate. + 2817526            ParameterExpression entity = Expression.Parameter(typeof(Entity)); + 2817527            var expTreeBody = TranslateQueryExpressionFiltersToExpression(context, qe, entity); + 2784528            Expression<Func<Entity, bool>> lambda = Expression.Lambda<Func<Entity, bool>>(expTreeBody, entity); + 2784529            query = query.Where(lambda);530531            //Sort results + 2784532             if (qe.Orders != null) + 2784533            { + 2784534                 if (qe.Orders.Count > 0) + 420535                { + 420536                    IOrderedQueryable<Entity> orderedQuery = null;537 + 420538                    var order = qe.Orders[0]; + 420539                     if (order.OrderType == OrderType.Ascending) + 384540                        orderedQuery = query.OrderBy(e => e.Attributes.ContainsKey(order.AttributeName) ? e[order.Attrib541                    else + 36542                        orderedQuery = query.OrderByDescending(e => e.Attributes.ContainsKey(order.AttributeName) ? e[or543544                    //Subsequent orders should use ThenBy and ThenByDescending + 888545                     for (var i = 1; i < qe.Orders.Count; i++) + 24546                    { + 24547                        var thenOrder = qe.Orders[i]; + 24548                         if (thenOrder.OrderType == OrderType.Ascending) + 12549                            orderedQuery = orderedQuery.ThenBy(e => e.Attributes.ContainsKey(thenOrder.AttributeName) ? 550                        else + 12551                            orderedQuery = orderedQuery.ThenByDescending(e => e[thenOrder.AttributeName], new XrmOrderBy + 24552                    }  553554            //Project the attributes in the root column set  (must be applied after the where and order clauses, not bef - 2746555            query = query.Select(x => x.Clone(x.GetType(), context).ProjectAttributes(qe, context));556 - 2746557            return query; - 2752558        }559 + 420554                    query = orderedQuery; + 420555                } + 2784556            }557558            //Project the attributes in the root column set  (must be applied after the where and order clauses, not bef + 2784559            query = query.Select(x => x.Clone(x.GetType(), context).ProjectAttributes(qe, context));  560561        protected static Expression TranslateConditionExpression(QueryExpression qe, XrmFakedContext context, TypedCondi - 2842562        { - 2842563            Expression attributesProperty = Expression.Property( - 2842564                entity, - 2842565                "Attributes" - 2842566                );567568569            //If the attribute comes from a joined entity, then we need to access the attribute from the join570            //But the entity name attribute only exists >= 2013571#if FAKE_XRM_EASY_2013 || FAKE_XRM_EASY_2015 || FAKE_XRM_EASY_2016 || FAKE_XRM_EASY_365 || FAKE_XRM_EASY_9 - 2394572            string attributeName = "";573574            //Do not prepend the entity name if the EntityLogicalName is the same as the QueryExpression main logical na + 2784561            return query; + 2790562        }563564#if !FAKE_XRM_EASY565        protected static void ValidateAliases(QueryExpression qe, XrmFakedContext context) + 2383566        { + 2383567             if (qe.Criteria != null) + 2218568                ValidateAliases(qe, context, qe.Criteria); + 2383569             if (qe.LinkEntities != null) + 9629570                foreach (var link in qe.LinkEntities) + 1240571                { + 1240572                    ValidateAliases(qe, context, link); + 1240573                } + 2383574        }  575 - 2394576             if (!string.IsNullOrWhiteSpace(c.CondExpression.EntityName) && !c.CondExpression.EntityName.Equals(qe.Entity - 75577            { - 75578                attributeName = c.CondExpression.EntityName + "." + c.CondExpression.AttributeName; - 75579            }580            else - 2319581                attributeName = c.CondExpression.AttributeName;582 - 2394583            Expression containsAttributeExpression = Expression.Call( - 2394584                attributesProperty, - 2394585                typeof(AttributeCollection).GetMethod("ContainsKey", new Type[] { typeof(string) }), - 2394586                Expression.Constant(attributeName) - 2394587                );588 - 2394589            Expression getAttributeValueExpr = Expression.Property( - 2394590                            attributesProperty, "Item", - 2394591                            Expression.Constant(attributeName, typeof(string)) - 2394592                            );593#else - 448594            Expression containsAttributeExpression = Expression.Call( - 448595                attributesProperty, - 448596                typeof(AttributeCollection).GetMethod("ContainsKey", new Type[] { typeof(string) }), - 448597                Expression.Constant(c.CondExpression.AttributeName) - 448598                );599 - 448600            Expression getAttributeValueExpr = Expression.Property( - 448601                            attributesProperty, "Item", - 448602                            Expression.Constant(c.CondExpression.AttributeName, typeof(string)) - 448603                            );604#endif605606607 - 2842608            Expression getNonBasicValueExpr = getAttributeValueExpr;609 - 2842610            Expression operatorExpression = null;611 - 2842612             switch (c.CondExpression.Operator)613            {614                case ConditionOperator.Equal:615                case ConditionOperator.Today:616                case ConditionOperator.Yesterday:617                case ConditionOperator.Tomorrow:618                case ConditionOperator.EqualUserId: - 2243619                    operatorExpression = TranslateConditionExpressionEqual(context, c, getNonBasicValueExpr, containsAtt - 2239620                    break;621622                case ConditionOperator.NotEqualUserId: - 6623                    operatorExpression = Expression.Not(TranslateConditionExpressionEqual(context, c, getNonBasicValueEx - 6624                    break;625626                case ConditionOperator.EqualBusinessId: - 6627                    operatorExpression = TranslateConditionExpressionEqual(context, c, getNonBasicValueExpr, containsAtt - 6628                    break;629630                case ConditionOperator.NotEqualBusinessId: - 0631                    operatorExpression = Expression.Not(TranslateConditionExpressionEqual(context, c, getNonBasicValueEx - 0632                    break;633634                case ConditionOperator.BeginsWith:635                case ConditionOperator.Like: - 54636                    operatorExpression = TranslateConditionExpressionLike(c, getNonBasicValueExpr, containsAttributeExpr - 54637                    break;638639                case ConditionOperator.EndsWith: - 18640                    operatorExpression = TranslateConditionExpressionEndsWith(c, getNonBasicValueExpr, containsAttribute - 18641                    break;642643                case ConditionOperator.Contains: - 24644                    operatorExpression = TranslateConditionExpressionContains(c, getNonBasicValueExpr, containsAttribute - 24645                    break;646647                case ConditionOperator.NotEqual: - 20648                    operatorExpression = Expression.Not(TranslateConditionExpressionEqual(context, c, getNonBasicValueEx - 20649                    break;650651                case ConditionOperator.DoesNotBeginWith:652                case ConditionOperator.DoesNotEndWith:653                case ConditionOperator.NotLike:654                case ConditionOperator.DoesNotContain: - 12655                    operatorExpression = Expression.Not(TranslateConditionExpressionLike(c, getNonBasicValueExpr, contai - 12656                    break;657658                case ConditionOperator.Null: - 47659                    operatorExpression = TranslateConditionExpressionNull(c, getNonBasicValueExpr, containsAttributeExpr - 47660                    break;661662                case ConditionOperator.NotNull: - 84663                    operatorExpression = Expression.Not(TranslateConditionExpressionNull(c, getNonBasicValueExpr, contai - 84664                    break;665666                case ConditionOperator.GreaterThan: - 24667                    operatorExpression = TranslateConditionExpressionGreaterThan(c, getNonBasicValueExpr, containsAttrib - 24668                    break;576        protected static void ValidateAliases(QueryExpression qe, XrmFakedContext context, LinkEntity link) + 1335577        { + 1335578             if (link.LinkCriteria != null) + 1250579                ValidateAliases(qe, context, link.LinkCriteria); + 1335580             if (link.LinkEntities != null) + 4195581                foreach (var innerLink in link.LinkEntities) + 95582                { + 95583                    ValidateAliases(qe, context, innerLink); + 95584                } + 1335585        }586587        protected static void ValidateAliases(QueryExpression qe, XrmFakedContext context, FilterExpression filter) + 3698588        { + 3698589             if (filter.Filters != null) + 11554590                foreach (var innerFilter in filter.Filters) + 230591                { + 230592                    ValidateAliases(qe, context, innerFilter); + 230593                }594 + 3698595             if (filter.Conditions != null) + 16034596                foreach (var condition in filter.Conditions) + 2470597                { + 2470598                     if (!string.IsNullOrEmpty(condition.EntityName)) + 100599                    { + 100600                        ValidateAliases(qe, context, condition); + 100601                    } + 2470602                } + 3698603        }604605        protected static void ValidateAliases(QueryExpression qe, XrmFakedContext context, ConditionExpression condition + 100606        { + 100607             var matches = qe.LinkEntities != null ? MatchByAlias(qe, context, condition, qe.LinkEntities) : 0; + 100608             if (matches > 1) + 0609            { + 0610                throw new FaultException<OrganizationServiceFault>(new OrganizationServiceFault(), $"Table {condition.En611            } + 100612             else if (matches == 0) + 15613            { + 30614                 if (qe.LinkEntities != null) matches = MatchByEntity(qe, context, condition, qe.LinkEntities); + 15615                 if (matches > 1) + 0616                { + 0617                    throw new FaultException<OrganizationServiceFault>(new OrganizationServiceFault(), $"There's more th618                } + 15619                 else if (matches == 0) + 5620                { + 10621                     if (condition.EntityName == qe.EntityName) return; + 0622                    throw new FaultException<OrganizationServiceFault>(new OrganizationServiceFault(), $"LinkEntity with623                } + 10624                condition.EntityName += "1"; + 10625            } + 100626        }627628        protected static int MatchByEntity(QueryExpression qe, XrmFakedContext context, ConditionExpression condition, D + 25629        { + 25630            var matches = 0; + 95631            foreach (var link in linkEntities) + 10632            { + 10633                 if (string.IsNullOrEmpty(link.EntityAlias) && condition.EntityName == link.LinkToEntityName) + 10634                { + 10635                    matches += 1; + 10636                } + 20637                 if (link.LinkEntities != null) matches += MatchByEntity(qe, context, condition, link.LinkEntities); + 10638            } + 25639            return matches; + 25640        }641642        protected static int MatchByAlias(QueryExpression qe, XrmFakedContext context, ConditionExpression condition, Da + 235643        { + 235644            var matches = 0; + 975645            foreach (var link in linkEntities) + 135646            { + 135647                 if (link.EntityAlias == condition.EntityName) + 85648                { + 85649                    matches += 1; + 85650                } + 270651                 if (link.LinkEntities != null) matches += MatchByAlias(qe, context, condition, link.LinkEntities); + 135652            } + 235653            return matches; + 235654        }655#endif656657        protected static Expression TranslateConditionExpression(QueryExpression qe, XrmFakedContext context, TypedCondi + 2922658        { + 2922659            Expression attributesProperty = Expression.Property( + 2922660                entity, + 2922661                "Attributes" + 2922662                );663664665            //If the attribute comes from a joined entity, then we need to access the attribute from the join666            //But the entity name attribute only exists >= 2013667#if FAKE_XRM_EASY_2013 || FAKE_XRM_EASY_2015 || FAKE_XRM_EASY_2016 || FAKE_XRM_EASY_365 || FAKE_XRM_EASY_9 + 2464668            string attributeName = "";  669670                case ConditionOperator.GreaterEqual: - 38671                    operatorExpression = TranslateConditionExpressionGreaterThanOrEqual(context, c, getNonBasicValueExpr - 38672                    break;673674                case ConditionOperator.LessThan: - 36675                    operatorExpression = TranslateConditionExpressionLessThan(c, getNonBasicValueExpr, containsAttribute - 36676                    break;677678                case ConditionOperator.LessEqual: - 28679                    operatorExpression = TranslateConditionExpressionLessThanOrEqual(context, c, getNonBasicValueExpr, c - 28680                    break;681682                case ConditionOperator.In: - 30683                    operatorExpression = TranslateConditionExpressionIn(c, getNonBasicValueExpr, containsAttributeExpres - 28684                    break;685686                case ConditionOperator.NotIn: - 2687                    operatorExpression = Expression.Not(TranslateConditionExpressionIn(c, getNonBasicValueExpr, contains - 2688                    break;689690                case ConditionOperator.On: - 12691                    operatorExpression = TranslateConditionExpressionEqual(context, c, getNonBasicValueExpr, containsAtt - 12692                    break;693694                case ConditionOperator.NotOn: - 0695                    operatorExpression = Expression.Not(TranslateConditionExpressionEqual(context, c, getNonBasicValueEx - 0696                    break;697698                case ConditionOperator.OnOrAfter: - 12699                    operatorExpression = Expression.Or( - 12700                               TranslateConditionExpressionEqual(context, c, getNonBasicValueExpr, containsAttributeExpr - 12701                               TranslateConditionExpressionGreaterThan(c, getNonBasicValueExpr, containsAttributeExpress - 12702                    break;703                case ConditionOperator.Last7Days: - 6704                    operatorExpression = TranslateConditionExpressionLast(c, getNonBasicValueExpr, containsAttributeExpr - 6705                    break;706707                case ConditionOperator.OnOrBefore: - 18708                    operatorExpression = Expression.Or( - 18709                                TranslateConditionExpressionEqual(context, c, getNonBasicValueExpr, containsAttributeExp - 18710                                TranslateConditionExpressionLessThan(c, getNonBasicValueExpr, containsAttributeExpressio - 18711                    break;712713                case ConditionOperator.Between: - 12714                     if (c.CondExpression.Values.Count != 2) - 6715                    { - 6716                        throw new Exception("Between operator requires exactly 2 values.");717                    } - 6718                    operatorExpression = TranslateConditionExpressionBetween(c, getNonBasicValueExpr, containsAttributeE - 6719                    break;720721                case ConditionOperator.NotBetween: - 12722                     if (c.CondExpression.Values.Count != 2) - 6723                    { - 6724                        throw new Exception("Not-Between operator requires exactly 2 values.");725                    } - 6726                    operatorExpression = Expression.Not(TranslateConditionExpressionBetween(c, getNonBasicValueExpr, con - 6727                    break;728                case ConditionOperator.OlderThanXMonths: - 12729                    var monthsToAdd = 0; - 12730                    var parsedMonths = int.TryParse(c.CondExpression.Values[0].ToString(), out monthsToAdd);731 - 12732                     if (parsedMonths == false) - 0733                    { - 0734                        throw new Exception("Older than X months requires an integer value in the ConditionExpression.")735                    }736 - 12737                     if (monthsToAdd <= 0) - 0738                    { - 0739                        throw new Exception("Older than X months requires a value greater than 0.");740                    }741 - 12742                    var olderThanDate = DateTime.Now.AddMonths(-monthsToAdd);743 - 12744                    operatorExpression = TranslateConditionExpressionOlderThan(c, getNonBasicValueExpr, containsAttribut - 12745                    break;670            //Do not prepend the entity name if the EntityLogicalName is the same as the QueryExpression main logical na671 + 2464672             if (!string.IsNullOrWhiteSpace(c.CondExpression.EntityName) && !c.CondExpression.EntityName.Equals(qe.Entity + 95673            { + 95674                attributeName = c.CondExpression.EntityName + "." + c.CondExpression.AttributeName; + 95675            }676            else + 2369677                attributeName = c.CondExpression.AttributeName;678 + 2464679            Expression containsAttributeExpression = Expression.Call( + 2464680                attributesProperty, + 2464681                typeof(AttributeCollection).GetMethod("ContainsKey", new Type[] { typeof(string) }), + 2464682                Expression.Constant(attributeName) + 2464683                );684 + 2464685            Expression getAttributeValueExpr = Expression.Property( + 2464686                            attributesProperty, "Item", + 2464687                            Expression.Constant(attributeName, typeof(string)) + 2464688                            );689#else + 458690            Expression containsAttributeExpression = Expression.Call( + 458691                attributesProperty, + 458692                typeof(AttributeCollection).GetMethod("ContainsKey", new Type[] { typeof(string) }), + 458693                Expression.Constant(c.CondExpression.AttributeName) + 458694                );695 + 458696            Expression getAttributeValueExpr = Expression.Property( + 458697                            attributesProperty, "Item", + 458698                            Expression.Constant(c.CondExpression.AttributeName, typeof(string)) + 458699                            );700#endif701702703 + 2922704            Expression getNonBasicValueExpr = getAttributeValueExpr;705 + 2922706            Expression operatorExpression = null;707 + 2922708             switch (c.CondExpression.Operator)709            {710                case ConditionOperator.Equal:711                case ConditionOperator.Today:712                case ConditionOperator.Yesterday:713                case ConditionOperator.Tomorrow:714                case ConditionOperator.EqualUserId: + 2263715                    operatorExpression = TranslateConditionExpressionEqual(context, c, getNonBasicValueExpr, containsAtt + 2259716                    break;717718                case ConditionOperator.NotEqualUserId: + 6719                    operatorExpression = Expression.Not(TranslateConditionExpressionEqual(context, c, getNonBasicValueEx + 6720                    break;721722                case ConditionOperator.EqualBusinessId: + 6723                    operatorExpression = TranslateConditionExpressionEqual(context, c, getNonBasicValueExpr, containsAtt + 6724                    break;725726                case ConditionOperator.NotEqualBusinessId: + 0727                    operatorExpression = Expression.Not(TranslateConditionExpressionEqual(context, c, getNonBasicValueEx + 0728                    break;729730                case ConditionOperator.BeginsWith:731                case ConditionOperator.Like: + 66732                    operatorExpression = TranslateConditionExpressionLike(c, getNonBasicValueExpr, containsAttributeExpr + 66733                    break;734735                case ConditionOperator.EndsWith: + 18736                    operatorExpression = TranslateConditionExpressionEndsWith(c, getNonBasicValueExpr, containsAttribute + 18737                    break;738739                case ConditionOperator.Contains: + 24740                    operatorExpression = TranslateConditionExpressionContains(c, getNonBasicValueExpr, containsAttribute + 24741                    break;742743                case ConditionOperator.NotEqual: + 20744                    operatorExpression = Expression.Not(TranslateConditionExpressionEqual(context, c, getNonBasicValueEx + 20745                    break;  746747                case ConditionOperator.NextXWeeks: - 6748                    operatorExpression = TranslateConditionExpressionNext(c, getNonBasicValueExpr, containsAttributeExpr - 6749                    break;750751                case ConditionOperator.ThisYear:752                case ConditionOperator.LastYear:753                case ConditionOperator.NextYear:754                case ConditionOperator.ThisMonth:755                case ConditionOperator.LastMonth:756                case ConditionOperator.NextMonth:757                case ConditionOperator.LastWeek:758                case ConditionOperator.ThisWeek:759                case ConditionOperator.NextWeek: - 54760                    operatorExpression = TranslateConditionExpressionBetweenDates(c, getNonBasicValueExpr, containsAttri - 54761                    break;762763                case ConditionOperator.Next7Days: - 6764                    { - 6765                        DateTime today = DateTime.Today; - 6766                        c.CondExpression.Values.Add(today); - 6767                        c.CondExpression.Values.Add(today.AddDays(7)); - 6768                        operatorExpression = TranslateConditionExpressionBetween(c, getAttributeValueExpr, containsAttri - 6769                    } - 6770                    break;771772#if FAKE_XRM_EASY_9773                case ConditionOperator.ContainValues: - 11774                    operatorExpression = TranslateConditionExpressionContainValues(c, getNonBasicValueExpr, containsAttr - 9775                    break;776777                case ConditionOperator.DoesNotContainValues: - 3778                    operatorExpression = Expression.Not(TranslateConditionExpressionContainValues(c, getNonBasicValueExp - 3779                    break;780#endif747                case ConditionOperator.DoesNotBeginWith:748                case ConditionOperator.DoesNotEndWith:749                case ConditionOperator.NotLike:750                case ConditionOperator.DoesNotContain: + 12751                    operatorExpression = Expression.Not(TranslateConditionExpressionLike(c, getNonBasicValueExpr, contai + 12752                    break;753754                case ConditionOperator.Null: + 71755                    operatorExpression = TranslateConditionExpressionNull(c, getNonBasicValueExpr, containsAttributeExpr + 71756                    break;757758                case ConditionOperator.NotNull: + 108759                    operatorExpression = Expression.Not(TranslateConditionExpressionNull(c, getNonBasicValueExpr, contai + 108760                    break;761762                case ConditionOperator.GreaterThan: + 24763                    operatorExpression = TranslateConditionExpressionGreaterThan(c, getNonBasicValueExpr, containsAttrib + 24764                    break;765766                case ConditionOperator.GreaterEqual: + 38767                    operatorExpression = TranslateConditionExpressionGreaterThanOrEqual(context, c, getNonBasicValueExpr + 38768                    break;769770                case ConditionOperator.LessThan: + 36771                    operatorExpression = TranslateConditionExpressionLessThan(c, getNonBasicValueExpr, containsAttribute + 36772                    break;773774                case ConditionOperator.LessEqual: + 28775                    operatorExpression = TranslateConditionExpressionLessThanOrEqual(context, c, getNonBasicValueExpr, c + 28776                    break;777778                case ConditionOperator.In: + 30779                    operatorExpression = TranslateConditionExpressionIn(c, getNonBasicValueExpr, containsAttributeExpres + 28780                    break;  781782                default: - 6783                    throw new PullRequestException(string.Format("Operator {0} not yet implemented for condition express784782                case ConditionOperator.NotIn: + 2783                    operatorExpression = Expression.Not(TranslateConditionExpressionIn(c, getNonBasicValueExpr, contains + 2784                    break;  785786            }787 - 2816788             if (c.IsOuter) - 44789            {790                //If outer join, filter is optional, only if there was a value - 44791                return Expression.Constant(true);792            }793            else - 2772794                return operatorExpression;795 - 2816796        }797798        private static void ValidateSupportedTypedExpression(TypedConditionExpression typedExpression) - 2843799        { - 2843800            Expression validateOperatorTypeExpression = Expression.Empty(); - 2843801            ConditionOperator[] supportedOperators = (ConditionOperator[])Enum.GetValues(typeof(ConditionOperator));786                case ConditionOperator.On: + 12787                    operatorExpression = TranslateConditionExpressionEqual(context, c, getNonBasicValueExpr, containsAtt + 12788                    break;789790                case ConditionOperator.NotOn: + 0791                    operatorExpression = Expression.Not(TranslateConditionExpressionEqual(context, c, getNonBasicValueEx + 0792                    break;793794                case ConditionOperator.OnOrAfter: + 12795                    operatorExpression = Expression.Or( + 12796                               TranslateConditionExpressionEqual(context, c, getNonBasicValueExpr, containsAttributeExpr + 12797                               TranslateConditionExpressionGreaterThan(c, getNonBasicValueExpr, containsAttributeExpress + 12798                    break;799                case ConditionOperator.Last7Days: + 6800                    operatorExpression = TranslateConditionExpressionLast(c, getNonBasicValueExpr, containsAttributeExpr + 6801                    break;  802803#if FAKE_XRM_EASY_9 - 511804             if (typedExpression.AttributeType == typeof(OptionSetValueCollection)) - 39805            { - 39806                supportedOperators = new[] - 39807                { - 39808                    ConditionOperator.ContainValues, - 39809                    ConditionOperator.DoesNotContainValues, - 39810                    ConditionOperator.Equal, - 39811                    ConditionOperator.NotEqual, - 39812                    ConditionOperator.NotNull, - 39813                    ConditionOperator.Null, - 39814                    ConditionOperator.In, - 39815                    ConditionOperator.NotIn, - 39816                }; - 39817            }818#endif819 - 2843820             if (!supportedOperators.Contains(typedExpression.CondExpression.Operator)) - 1821            { - 1822                OrganizationServiceFaultOperatorIsNotValidException.Throw(); - 0823            } - 2842824        }825826        protected static Expression GetAppropiateTypedValue(object value) - 565827        {828            //Basic types conversions829            //Special case => datetime is sent as a string - 565830             if (value is string) - 152831            {832                DateTime dtDateTimeConversion; - 152833                 if (DateTime.TryParse(value.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal,  - 0834                { - 0835                    return Expression.Constant(dtDateTimeConversion, typeof(DateTime));836                }837                else - 152838                { - 152839                    return GetCaseInsensitiveExpression(Expression.Constant(value, typeof(string)));840                }841            } - 413842             else if (value is EntityReference) - 12843            { - 12844                var cast = (value as EntityReference).Id; - 12845                return Expression.Constant(cast);846            } - 401847             else if (value is OptionSetValue) - 0848            { - 0849                var cast = (value as OptionSetValue).Value; - 0850                return Expression.Constant(cast);851            } - 401852             else if (value is Money) - 0853            { - 0854                var cast = (value as Money).Value; - 0855                return Expression.Constant(cast);856            } - 401857            return Expression.Constant(value); - 565858        }859860        protected static Type GetAppropiateTypeForValue(object value) - 114861        {862            //Basic types conversions863            //Special case => datetime is sent as a string - 114864             if (value is string) - 6865            {866                DateTime dtDateTimeConversion; - 6867                 if (DateTime.TryParse(value.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal,  - 0868                { - 0869                    return typeof(DateTime);870                }871                else - 6872                { - 6873                    return typeof(string);874                }875            }876            else - 108877                return value.GetType(); - 114878        }879880        protected static Expression GetAppropiateTypedValueAndType(object value, Type attributeType) - 2758881        { - 2758882             if (attributeType == null) - 565883                return GetAppropiateTypedValue(value);884885886            //Basic types conversions887            //Special case => datetime is sent as a string - 2193888             if (value is string) - 623889            {890                int iValue;803                case ConditionOperator.OnOrBefore: + 18804                    operatorExpression = Expression.Or( + 18805                                TranslateConditionExpressionEqual(context, c, getNonBasicValueExpr, containsAttributeExp + 18806                                TranslateConditionExpressionLessThan(c, getNonBasicValueExpr, containsAttributeExpressio + 18807                    break;808809                case ConditionOperator.Between: + 12810                     if (c.CondExpression.Values.Count != 2) + 6811                    { + 6812                        throw new Exception("Between operator requires exactly 2 values.");813                    } + 6814                    operatorExpression = TranslateConditionExpressionBetween(c, getNonBasicValueExpr, containsAttributeE + 6815                    break;816817                case ConditionOperator.NotBetween: + 12818                     if (c.CondExpression.Values.Count != 2) + 6819                    { + 6820                        throw new Exception("Not-Between operator requires exactly 2 values.");821                    } + 6822                    operatorExpression = Expression.Not(TranslateConditionExpressionBetween(c, getNonBasicValueExpr, con + 6823                    break;824                case ConditionOperator.OlderThanXMonths: + 12825                    var monthsToAdd = 0; + 12826                    var parsedMonths = int.TryParse(c.CondExpression.Values[0].ToString(), out monthsToAdd);827 + 12828                     if (parsedMonths == false) + 0829                    { + 0830                        throw new Exception("Older than X months requires an integer value in the ConditionExpression.")831                    }832 + 12833                     if (monthsToAdd <= 0) + 0834                    { + 0835                        throw new Exception("Older than X months requires a value greater than 0.");836                    }837 + 12838                    var olderThanDate = DateTime.Now.AddMonths(-monthsToAdd);839 + 12840                    operatorExpression = TranslateConditionExpressionOlderThan(c, getNonBasicValueExpr, containsAttribut + 12841                    break;842843                case ConditionOperator.NextXWeeks: + 6844                    operatorExpression = TranslateConditionExpressionNext(c, getNonBasicValueExpr, containsAttributeExpr + 6845                    break;846847                case ConditionOperator.ThisYear:848                case ConditionOperator.LastYear:849                case ConditionOperator.NextYear:850                case ConditionOperator.ThisMonth:851                case ConditionOperator.LastMonth:852                case ConditionOperator.NextMonth:853                case ConditionOperator.LastWeek:854                case ConditionOperator.ThisWeek:855                case ConditionOperator.NextWeek: + 54856                    operatorExpression = TranslateConditionExpressionBetweenDates(c, getNonBasicValueExpr, containsAttri + 54857                    break;858859                case ConditionOperator.Next7Days: + 6860                    { + 6861                        DateTime today = DateTime.Today; + 6862                        c.CondExpression.Values.Add(today); + 6863                        c.CondExpression.Values.Add(today.AddDays(7)); + 6864                        operatorExpression = TranslateConditionExpressionBetween(c, getAttributeValueExpr, containsAttri + 6865                    } + 6866                    break;867868#if FAKE_XRM_EASY_9869                case ConditionOperator.ContainValues: + 11870                    operatorExpression = TranslateConditionExpressionContainValues(c, getNonBasicValueExpr, containsAttr + 9871                    break;872873                case ConditionOperator.DoesNotContainValues: + 3874                    operatorExpression = Expression.Not(TranslateConditionExpressionContainValues(c, getNonBasicValueExp + 3875                    break;876#endif877878                default: + 6879                    throw new PullRequestException(string.Format("Operator {0} not yet implemented for condition express880881882            }883 + 2896884             if (c.IsOuter) + 44885            {886                //If outer join, filter is optional, only if there was a value + 44887                return Expression.Constant(true);888            }889            else + 2852890                return operatorExpression;  891892                DateTime dtDateTimeConversion;893                Guid id; - 623894                 if (attributeType.IsDateTime()  //Only convert to DateTime if the attribute's type was DateTime - 623895                    && DateTime.TryParse(value.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversa - 6896                { - 6897                    return Expression.Constant(dtDateTimeConversion, typeof(DateTime));898                } - 617899                 else if (attributeType.IsOptionSet() && int.TryParse(value.ToString(), out iValue)) - 6900                { - 6901                    return Expression.Constant(iValue, typeof(int));902                } - 611903                 else if (attributeType == typeof(EntityReference) && Guid.TryParse((string)value, out id)) - 6904                { - 6905                    return Expression.Constant(id);906                }907                else - 605908                { - 605909                    return GetCaseInsensitiveExpression(Expression.Constant(value, typeof(string)));910                }911            } - 1570912             else if (value is EntityReference) - 23913            { - 23914                var cast = (value as EntityReference).Id; - 23915                return Expression.Constant(cast);916            } - 1547917             else if (value is OptionSetValue) - 46918            { - 46919                var cast = (value as OptionSetValue).Value; - 46920                return Expression.Constant(cast);921            } - 1501922             else if (value is Money) - 6923            { - 6924                var cast = (value as Money).Value; - 6925                return Expression.Constant(cast);926            } - 1495927            return Expression.Constant(value); - 2758928        }929930        protected static Expression GetAppropiateCastExpressionBasedOnType(Type t, Expression input, object value) - 2900931        { - 2900932            var typedExpression = GetAppropiateCastExpressionBasedOnAttributeTypeOrValue(input, value, t);933934            //Now, any value (entity reference, string, int, etc,... could be wrapped in an AliasedValue object935            //So let's add this - 2900936            var getValueFromAliasedValueExp = Expression.Call(Expression.Convert(input, typeof(AliasedValue)), - 2900937                                            typeof(AliasedValue).GetMethod("get_Value"));938 - 2900939            var exp = Expression.Condition(Expression.TypeIs(input, typeof(AliasedValue)), - 2900940                    GetAppropiateCastExpressionBasedOnAttributeTypeOrValue(getValueFromAliasedValueExp, value, t), - 2900941                    typedExpression //Not an aliased value - 2900942                );943 - 2900944            return exp; - 2900945        }946947        //protected static Expression GetAppropiateCastExpressionBasedOnValue(XrmFakedContext context, Expression input,948        //{949        //    var typedExpression = GetAppropiateCastExpressionBasedOnAttributeTypeOrValue(context, input, value, sEntit950951        //    //Now, any value (entity reference, string, int, etc,... could be wrapped in an AliasedValue object952        //    //So let's add this953        //    var getValueFromAliasedValueExp = Expression.Call(Expression.Convert(input, typeof(AliasedValue)),954        //                                    typeof(AliasedValue).GetMethod("get_Value")); + 2896892        }893894        private static void ValidateSupportedTypedExpression(TypedConditionExpression typedExpression) + 2923895        { + 2923896            Expression validateOperatorTypeExpression = Expression.Empty(); + 2923897            ConditionOperator[] supportedOperators = (ConditionOperator[])Enum.GetValues(typeof(ConditionOperator));898899#if FAKE_XRM_EASY_9 + 525900             if (typedExpression.AttributeType == typeof(OptionSetValueCollection)) + 39901            { + 39902                supportedOperators = new[] + 39903                { + 39904                    ConditionOperator.ContainValues, + 39905                    ConditionOperator.DoesNotContainValues, + 39906                    ConditionOperator.Equal, + 39907                    ConditionOperator.NotEqual, + 39908                    ConditionOperator.NotNull, + 39909                    ConditionOperator.Null, + 39910                    ConditionOperator.In, + 39911                    ConditionOperator.NotIn, + 39912                }; + 39913            }914#endif915 + 2923916             if (!supportedOperators.Contains(typedExpression.CondExpression.Operator)) + 1917            { + 1918                OrganizationServiceFaultOperatorIsNotValidException.Throw(); + 0919            } + 2922920        }921922        protected static Expression GetAppropiateTypedValue(object value) + 585923        {924            //Basic types conversions925            //Special case => datetime is sent as a string + 585926             if (value is string) + 162927            {928                DateTime dtDateTimeConversion; + 162929                 if (DateTime.TryParse(value.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal,  + 0930                { + 0931                    return Expression.Constant(dtDateTimeConversion, typeof(DateTime));932                }933                else + 162934                { + 162935                    return GetCaseInsensitiveExpression(Expression.Constant(value, typeof(string)));936                }937            } + 423938             else if (value is EntityReference) + 12939            { + 12940                var cast = (value as EntityReference).Id; + 12941                return Expression.Constant(cast);942            } + 411943             else if (value is OptionSetValue) + 0944            { + 0945                var cast = (value as OptionSetValue).Value; + 0946                return Expression.Constant(cast);947            } + 411948             else if (value is Money) + 0949            { + 0950                var cast = (value as Money).Value; + 0951                return Expression.Constant(cast);952            } + 411953            return Expression.Constant(value); + 585954        }  955956        //    var  exp = Expression.Condition(Expression.TypeIs(input, typeof(AliasedValue)),957        //            GetAppropiateCastExpressionBasedOnAttributeTypeOrValue(context, getValueFromAliasedValueExp, value958        //            typedExpression //Not an aliased value959        //        );960961        //    return exp;962        //}963964        protected static Expression GetAppropiateCastExpressionBasedOnValueInherentType(Expression input, object value) - 1166965        { - 1166966             if (value is Guid || value is EntityReference) - 454967                return GetAppropiateCastExpressionBasedGuid(input); //Could be compared against an EntityReference - 712968             if (value is int || value is OptionSetValue) - 192969                return GetAppropiateCastExpressionBasedOnInt(input); //Could be compared against an OptionSet - 520970             if (value is decimal || value is Money) - 0971                return GetAppropiateCastExpressionBasedOnDecimal(input); //Could be compared against a Money - 520972             if (value is bool) - 84973                return GetAppropiateCastExpressionBasedOnBoolean(input); //Could be a BooleanManagedProperty - 436974             if (value is string) - 340975            { - 340976                return GetAppropiateCastExpressionBasedOnString(input, value);977            } - 96978            return GetAppropiateCastExpressionDefault(input, value); //any other type - 1166979        }956        protected static Type GetAppropiateTypeForValue(object value) + 114957        {958            //Basic types conversions959            //Special case => datetime is sent as a string + 114960             if (value is string) + 6961            {962                DateTime dtDateTimeConversion; + 6963                 if (DateTime.TryParse(value.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal,  + 0964                { + 0965                    return typeof(DateTime);966                }967                else + 6968                { + 6969                    return typeof(string);970                }971            }972            else + 108973                return value.GetType(); + 114974        }975976        protected static Expression GetAppropiateTypedValueAndType(object value, Type attributeType) + 2778977        { + 2778978             if (attributeType == null) + 585979                return GetAppropiateTypedValue(value);  980981        protected static Expression GetAppropiateCastExpressionBasedOnAttributeTypeOrValue(Expression input, object valu - 5800982        { - 5800983             if (attributeType != null) - 4634984            {985986#if FAKE_XRM_EASY || FAKE_XRM_EASY_2013 || FAKE_XRM_EASY_2015 - 2266987                 if (attributeType == typeof(Microsoft.Xrm.Client.CrmEntityReference)) - 0988                    return GetAppropiateCastExpressionBasedGuid(input);989#endif - 4634990                 if (attributeType == typeof(Guid)) - 518991                    return GetAppropiateCastExpressionBasedGuid(input); - 4116992                 if (attributeType == typeof(EntityReference)) - 454993                    return GetAppropiateCastExpressionBasedOnEntityReference(input, value); - 3662994                 if (attributeType == typeof(int) || attributeType == typeof(Nullable<int>) || attributeType.IsOptionSet( - 1150995                    return GetAppropiateCastExpressionBasedOnInt(input); - 2512996                 if (attributeType == typeof(decimal) || attributeType == typeof(Money)) - 32997                    return GetAppropiateCastExpressionBasedOnDecimal(input); - 2480998                 if (attributeType == typeof(bool) || attributeType == typeof(BooleanManagedProperty)) - 52999                    return GetAppropiateCastExpressionBasedOnBoolean(input); - 24281000                 if (attributeType == typeof(string)) - 13781001                    return GetAppropiateCastExpressionBasedOnStringAndType(input, value, attributeType); - 10501002                 if (attributeType.IsDateTime()) - 6241003                    return GetAppropiateCastExpressionBasedOnDateTime(input, value);1004#if FAKE_XRM_EASY_9 - 841005                 if (attributeType.IsOptionSetValueCollection()) - 681006                    return GetAppropiateCastExpressionBasedOnOptionSetValueCollection(input);1007#endif1008 - 3581009                return GetAppropiateCastExpressionDefault(input, value); //any other type1010            }1011 - 11661012            return GetAppropiateCastExpressionBasedOnValueInherentType(input, value); //Dynamic entities - 58001013        }1014        protected static Expression GetAppropiateCastExpressionBasedOnString(Expression input, object value) - 3401015        { - 3401016            var defaultStringExpression = GetCaseInsensitiveExpression(GetAppropiateCastExpressionDefault(input, value))10171018            DateTime dtDateTimeConversion; - 3401019             if (DateTime.TryParse(value.ToString(), out dtDateTimeConversion)) - 01020            { - 01021                return Expression.Convert(input, typeof(DateTime));981982            //Basic types conversions983            //Special case => datetime is sent as a string + 2193984             if (value is string) + 623985            {986                int iValue;987988                DateTime dtDateTimeConversion;989                Guid id; + 623990                 if (attributeType.IsDateTime()  //Only convert to DateTime if the attribute's type was DateTime + 623991                    && DateTime.TryParse(value.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversa + 6992                { + 6993                    return Expression.Constant(dtDateTimeConversion, typeof(DateTime));994                } + 617995                 else if (attributeType.IsOptionSet() && int.TryParse(value.ToString(), out iValue)) + 6996                { + 6997                    return Expression.Constant(iValue, typeof(int));998                } + 611999                 else if (attributeType == typeof(EntityReference) && Guid.TryParse((string)value, out id)) + 61000                { + 61001                    return Expression.Constant(id);1002                }1003                else + 6051004                { + 6051005                    return GetCaseInsensitiveExpression(Expression.Constant(value, typeof(string)));1006                }1007            } + 15701008             else if (value is EntityReference) + 231009            { + 231010                var cast = (value as EntityReference).Id; + 231011                return Expression.Constant(cast);1012            } + 15471013             else if (value is OptionSetValue) + 461014            { + 461015                var cast = (value as OptionSetValue).Value; + 461016                return Expression.Constant(cast);1017            } + 15011018             else if (value is Money) + 61019            { + 61020                var cast = (value as Money).Value; + 61021                return Expression.Constant(cast);  1022            }10231024            int iValue; - 3401025             if (int.TryParse(value.ToString(), out iValue)) - 521026            { - 521027                return Expression.Condition(Expression.TypeIs(input, typeof(OptionSetValue)), - 521028                    GetToStringExpression<Int32>(GetAppropiateCastExpressionBasedOnInt(input)), - 521029                    defaultStringExpression - 521030                );1031            }1032 - 2881033            return defaultStringExpression; - 3401034        }10351036        protected static Expression GetAppropiateCastExpressionBasedOnStringAndType(Expression input, object value, Type - 13781037        { - 13781038            var defaultStringExpression = GetCaseInsensitiveExpression(GetAppropiateCastExpressionDefault(input, value)) + 14951023            return Expression.Constant(value); + 27781024        }10251026        protected static Expression GetAppropiateCastExpressionBasedOnType(Type t, Expression input, object value) + 29321027        { + 29321028            var typedExpression = GetAppropiateCastExpressionBasedOnAttributeTypeOrValue(input, value, t);10291030            //Now, any value (entity reference, string, int, etc,... could be wrapped in an AliasedValue object1031            //So let's add this + 29321032            var getValueFromAliasedValueExp = Expression.Call(Expression.Convert(input, typeof(AliasedValue)), + 29321033                                            typeof(AliasedValue).GetMethod("get_Value"));1034 + 29321035            var exp = Expression.Condition(Expression.TypeIs(input, typeof(AliasedValue)), + 29321036                    GetAppropiateCastExpressionBasedOnAttributeTypeOrValue(getValueFromAliasedValueExp, value, t), + 29321037                    typedExpression //Not an aliased value + 29321038                );  10391040            int iValue; - 13781041             if (attributeType.IsOptionSet() && int.TryParse(value.ToString(), out iValue)) - 01042            { - 01043                return Expression.Condition(Expression.TypeIs(input, typeof(OptionSetValue)), - 01044                    GetToStringExpression<Int32>(GetAppropiateCastExpressionBasedOnInt(input)), - 01045                    defaultStringExpression - 01046                );1047            }1048 - 13781049            return defaultStringExpression; - 13781050        } + 29321040            return exp; + 29321041        }10421043        //protected static Expression GetAppropiateCastExpressionBasedOnValue(XrmFakedContext context, Expression input,1044        //{1045        //    var typedExpression = GetAppropiateCastExpressionBasedOnAttributeTypeOrValue(context, input, value, sEntit10461047        //    //Now, any value (entity reference, string, int, etc,... could be wrapped in an AliasedValue object1048        //    //So let's add this1049        //    var getValueFromAliasedValueExp = Expression.Call(Expression.Convert(input, typeof(AliasedValue)),1050        //                                    typeof(AliasedValue).GetMethod("get_Value"));  10511052        protected static Expression GetAppropiateCastExpressionBasedOnDateTime(Expression input, object value) - 6241053        {1054            // Convert to DateTime if string1055            DateTime _; - 6241056             if (value is DateTime || value is string && DateTime.TryParse(value.ToString(), out _)) - 6241057            { - 6241058                return Expression.Convert(input, typeof(DateTime));1059            }1060 - 01061            return input; // return directly - 6241062        }10631064        protected static Expression GetAppropiateCastExpressionDefault(Expression input, object value) - 21721065        { - 21721066            return Expression.Convert(input, value.GetType());  //Default type conversion - 21721067        }1068        protected static Expression GetAppropiateCastExpressionBasedGuid(Expression input) - 9721069        { - 9721070            var getIdFromEntityReferenceExpr = Expression.Call(Expression.TypeAs(input, typeof(EntityReference)), - 9721071                typeof(EntityReference).GetMethod("get_Id"));1072 - 9721073            return Expression.Condition( - 9721074                Expression.TypeIs(input, typeof(EntityReference)),  //If input is an entity reference, compare the Guid  - 9721075                Expression.Convert( - 9721076                    getIdFromEntityReferenceExpr, - 9721077                    typeof(Guid)), - 9721078                Expression.Condition(Expression.TypeIs(input, typeof(Guid)),  //If any other case, then just compare it  - 9721079                    Expression.Convert(input, typeof(Guid)), - 9721080                    Expression.Constant(Guid.Empty, typeof(Guid)))); - 9721081        }10821083        protected static Expression GetAppropiateCastExpressionBasedOnEntityReference(Expression input, object value) - 4541084        {1085            Guid guid; - 4541086             if (value is string && !Guid.TryParse((string)value, out guid)) - 121087            { - 121088                var getNameFromEntityReferenceExpr = Expression.Call(Expression.TypeAs(input, typeof(EntityReference)), - 121089                    typeof(EntityReference).GetMethod("get_Name"));1090 - 121091                return GetCaseInsensitiveExpression(Expression.Condition(Expression.TypeIs(input, typeof(EntityReference - 121092                    Expression.Convert(getNameFromEntityReferenceExpr, typeof(string)), - 121093                    Expression.Constant(string.Empty, typeof(string))));1094            }1095 - 4421096            var getIdFromEntityReferenceExpr = Expression.Call(Expression.TypeAs(input, typeof(EntityReference)), - 4421097                typeof(EntityReference).GetMethod("get_Id"));1098 - 4421099            return Expression.Condition( - 4421100                Expression.TypeIs(input, typeof(EntityReference)),  //If input is an entity reference, compare the Guid  - 4421101                Expression.Convert( - 4421102                    getIdFromEntityReferenceExpr, - 4421103                    typeof(Guid)), - 4421104                Expression.Condition(Expression.TypeIs(input, typeof(Guid)),  //If any other case, then just compare it  - 4421105                    Expression.Convert(input, typeof(Guid)), - 4421106                    Expression.Constant(Guid.Empty, typeof(Guid))));1052        //    var  exp = Expression.Condition(Expression.TypeIs(input, typeof(AliasedValue)),1053        //            GetAppropiateCastExpressionBasedOnAttributeTypeOrValue(context, getValueFromAliasedValueExp, value1054        //            typedExpression //Not an aliased value1055        //        );10561057        //    return exp;1058        //}10591060        protected static Expression GetAppropiateCastExpressionBasedOnValueInherentType(Expression input, object value) + 12181061        { + 12181062             if (value is Guid || value is EntityReference) + 4541063                return GetAppropiateCastExpressionBasedGuid(input); //Could be compared against an EntityReference + 7641064             if (value is int || value is OptionSetValue) + 1921065                return GetAppropiateCastExpressionBasedOnInt(input); //Could be compared against an OptionSet + 5721066             if (value is decimal || value is Money) + 01067                return GetAppropiateCastExpressionBasedOnDecimal(input); //Could be compared against a Money + 5721068             if (value is bool) + 1041069                return GetAppropiateCastExpressionBasedOnBoolean(input); //Could be a BooleanManagedProperty + 4681070             if (value is string) + 3721071            { + 3721072                return GetAppropiateCastExpressionBasedOnString(input, value);1073            } + 961074            return GetAppropiateCastExpressionDefault(input, value); //any other type + 12181075        }10761077        protected static Expression GetAppropiateCastExpressionBasedOnAttributeTypeOrValue(Expression input, object valu + 58641078        { + 58641079             if (attributeType != null) + 46461080            {10811082#if FAKE_XRM_EASY || FAKE_XRM_EASY_2013 || FAKE_XRM_EASY_2015 + 22721083                 if (attributeType == typeof(Microsoft.Xrm.Client.CrmEntityReference)) + 01084                    return GetAppropiateCastExpressionBasedGuid(input);1085#endif + 46461086                 if (attributeType == typeof(Guid)) + 5181087                    return GetAppropiateCastExpressionBasedGuid(input); + 41281088                 if (attributeType == typeof(EntityReference)) + 4541089                    return GetAppropiateCastExpressionBasedOnEntityReference(input, value); + 36741090                 if (attributeType == typeof(int) || attributeType == typeof(Nullable<int>) || attributeType.IsOptionSet( + 11501091                    return GetAppropiateCastExpressionBasedOnInt(input); + 25241092                 if (attributeType == typeof(decimal) || attributeType == typeof(Money)) + 321093                    return GetAppropiateCastExpressionBasedOnDecimal(input); + 24921094                 if (attributeType == typeof(bool) || attributeType == typeof(BooleanManagedProperty)) + 521095                    return GetAppropiateCastExpressionBasedOnBoolean(input); + 24401096                 if (attributeType == typeof(string)) + 13901097                    return GetAppropiateCastExpressionBasedOnStringAndType(input, value, attributeType); + 10501098                 if (attributeType.IsDateTime()) + 6241099                    return GetAppropiateCastExpressionBasedOnDateTime(input, value);1100#if FAKE_XRM_EASY_9 + 841101                 if (attributeType.IsOptionSetValueCollection()) + 681102                    return GetAppropiateCastExpressionBasedOnOptionSetValueCollection(input);1103#endif1104 + 3581105                return GetAppropiateCastExpressionDefault(input, value); //any other type1106            }  1107 - 4541108        }11091110        protected static Expression GetAppropiateCastExpressionBasedOnDecimal(Expression input) - 321111        { - 321112            return Expression.Condition( - 321113                        Expression.TypeIs(input, typeof(Money)), - 321114                                Expression.Convert( - 321115                                    Expression.Call(Expression.TypeAs(input, typeof(Money)), - 321116                                            typeof(Money).GetMethod("get_Value")), - 321117                                            typeof(decimal)), - 321118                           Expression.Condition(Expression.TypeIs(input, typeof(decimal)), - 321119                                        Expression.Convert(input, typeof(decimal)), - 321120                                        Expression.Constant(0.0M)));1121 - 321122        }11231124        protected static Expression GetAppropiateCastExpressionBasedOnBoolean(Expression input) - 1361125        { - 1361126            return Expression.Condition( - 1361127                        Expression.TypeIs(input, typeof(BooleanManagedProperty)), - 1361128                                Expression.Convert( - 1361129                                    Expression.Call(Expression.TypeAs(input, typeof(BooleanManagedProperty)), - 1361130                                            typeof(BooleanManagedProperty).GetMethod("get_Value")), - 1361131                                            typeof(bool)), - 1361132                           Expression.Condition(Expression.TypeIs(input, typeof(bool)), - 1361133                                        Expression.Convert(input, typeof(bool)), - 1361134                                        Expression.Constant(false))); + 12181108            return GetAppropiateCastExpressionBasedOnValueInherentType(input, value); //Dynamic entities + 58641109        }1110        protected static Expression GetAppropiateCastExpressionBasedOnString(Expression input, object value) + 3721111        { + 3721112            var defaultStringExpression = GetCaseInsensitiveExpression(GetAppropiateCastExpressionDefault(input, value))11131114            DateTime dtDateTimeConversion; + 3721115             if (DateTime.TryParse(value.ToString(), out dtDateTimeConversion)) + 01116            { + 01117                return Expression.Convert(input, typeof(DateTime));1118            }11191120            int iValue; + 3721121             if (int.TryParse(value.ToString(), out iValue)) + 521122            { + 521123                return Expression.Condition(Expression.TypeIs(input, typeof(OptionSetValue)), + 521124                    GetToStringExpression<Int32>(GetAppropiateCastExpressionBasedOnInt(input)), + 521125                    defaultStringExpression + 521126                );1127            }1128 + 3201129            return defaultStringExpression; + 3721130        }11311132        protected static Expression GetAppropiateCastExpressionBasedOnStringAndType(Expression input, object value, Type + 13901133        { + 13901134            var defaultStringExpression = GetCaseInsensitiveExpression(GetAppropiateCastExpressionDefault(input, value))  1135 - 1361136        }11371138        protected static Expression GetAppropiateCastExpressionBasedOnInt(Expression input) - 13941139        { - 13941140            return Expression.Condition( - 13941141                        Expression.TypeIs(input, typeof(OptionSetValue)), - 13941142                                            Expression.Convert( - 13941143                                                Expression.Call(Expression.TypeAs(input, typeof(OptionSetValue)), - 13941144                                                        typeof(OptionSetValue).GetMethod("get_Value")), - 13941145                                                        typeof(int)), - 13941146                                                    Expression.Convert(input, typeof(int))); - 13941147        }11481149        protected static Expression GetAppropiateCastExpressionBasedOnOptionSetValueCollection(Expression input) - 681150        { - 681151            return Expression.Call(typeof(XrmFakedContext).GetMethod("ConvertToHashSetOfInt"), input, Expression.Constan - 681152        }11531154#if FAKE_XRM_EASY_91155        public static HashSet<int> ConvertToHashSetOfInt(object input, bool isOptionSetValueCollectionAccepted) - 1441156        { - 1441157            var set = new HashSet<int>();1158 - 1441159             var faultReason = $"The formatter threw an exception while trying to deserialize the message: There was an e - 1441160                $" http://schemas.microsoft.com/xrm/2011/Contracts/Services:query. The InnerException message was 'Error - 1441161                $"'http://schemas.microsoft.com/2003/10/Serialization/Arrays:anyType' contains data from a type that map - 1441162                $"'http://schemas.microsoft.com/xrm/2011/Contracts:{input?.GetType()}'. The deserializer has no knowledg - 1441163                $"Consider changing the implementation of the ResolveName method on your DataContractResolver to return  - 1441164                $"'{input?.GetType()}' and namespace 'http://schemas.microsoft.com/xrm/2011/Contracts'.'.  Please see In1165 - 1441166             if (input is int) - 41167            { - 41168                set.Add((int)input); - 41169            } - 1401170             else if (input is string) - 11171            { - 11172                set.Add(int.Parse(input as string)); - 11173            } - 1391174             else if (input is int[]) - 01175            { - 01176                set.UnionWith(input as int[]); - 01177            } - 1391178             else if (input is string[]) - 01179            { - 01180                set.UnionWith((input as string[]).Select(s => int.Parse(s))); - 01181            } - 1391182             else if (input is DataCollection<object>) - 281183            { - 281184                var collection = input as DataCollection<object>;1185 - 621186                 if (collection.All(o => o is int)) - 71187                { - 71188                    set.UnionWith(collection.Cast<int>()); - 71189                } - 491190                 else if (collection.All(o => o is string)) - 91191                { - 251192                    set.UnionWith(collection.Select(o => int.Parse(o as string))); - 91193                } - 121194                 else if (collection.Count == 1 && collection[0] is int[]) - 81195                { - 81196                    set.UnionWith(collection[0] as int[]); - 81197                } - 41198                 else if (collection.Count == 1 && collection[0] is string[]) - 01199                { - 01200                    set.UnionWith((collection[0] as string[]).Select(s => int.Parse(s))); - 01201                }1202                else - 41203                { - 41204                    throw new FaultException(new FaultReason(faultReason));1205                } - 241206            } - 1111207             else if (isOptionSetValueCollectionAccepted && input is OptionSetValueCollection) - 1101208            { - 3261209                set.UnionWith((input as OptionSetValueCollection).Select(osv => osv.Value)); - 1101210            }1211            else - 11212            { - 11213                throw new FaultException(new FaultReason(faultReason));1214            }1215 - 1391216            return set; - 1391217        }1218#endif1136            int iValue; + 13901137             if (attributeType.IsOptionSet() && int.TryParse(value.ToString(), out iValue)) + 01138            { + 01139                return Expression.Condition(Expression.TypeIs(input, typeof(OptionSetValue)), + 01140                    GetToStringExpression<Int32>(GetAppropiateCastExpressionBasedOnInt(input)), + 01141                    defaultStringExpression + 01142                );1143            }1144 + 13901145            return defaultStringExpression; + 13901146        }11471148        protected static Expression GetAppropiateCastExpressionBasedOnDateTime(Expression input, object value) + 6241149        {1150            // Convert to DateTime if string1151            DateTime _; + 6241152             if (value is DateTime || value is string && DateTime.TryParse(value.ToString(), out _)) + 6241153            { + 6241154                return Expression.Convert(input, typeof(DateTime));1155            }1156 + 01157            return input; // return directly + 6241158        }11591160        protected static Expression GetAppropiateCastExpressionDefault(Expression input, object value) + 22161161        { + 22161162            return Expression.Convert(input, value.GetType());  //Default type conversion + 22161163        }1164        protected static Expression GetAppropiateCastExpressionBasedGuid(Expression input) + 9721165        { + 9721166            var getIdFromEntityReferenceExpr = Expression.Call(Expression.TypeAs(input, typeof(EntityReference)), + 9721167                typeof(EntityReference).GetMethod("get_Id"));1168 + 9721169            return Expression.Condition( + 9721170                Expression.TypeIs(input, typeof(EntityReference)),  //If input is an entity reference, compare the Guid  + 9721171                Expression.Convert( + 9721172                    getIdFromEntityReferenceExpr, + 9721173                    typeof(Guid)), + 9721174                Expression.Condition(Expression.TypeIs(input, typeof(Guid)),  //If any other case, then just compare it  + 9721175                    Expression.Convert(input, typeof(Guid)), + 9721176                    Expression.Constant(Guid.Empty, typeof(Guid)))); + 9721177        }11781179        protected static Expression GetAppropiateCastExpressionBasedOnEntityReference(Expression input, object value) + 4541180        {1181            Guid guid; + 4541182             if (value is string && !Guid.TryParse((string)value, out guid)) + 121183            { + 121184                var getNameFromEntityReferenceExpr = Expression.Call(Expression.TypeAs(input, typeof(EntityReference)), + 121185                    typeof(EntityReference).GetMethod("get_Name"));1186 + 121187                return GetCaseInsensitiveExpression(Expression.Condition(Expression.TypeIs(input, typeof(EntityReference + 121188                    Expression.Convert(getNameFromEntityReferenceExpr, typeof(string)), + 121189                    Expression.Constant(string.Empty, typeof(string))));1190            }1191 + 4421192            var getIdFromEntityReferenceExpr = Expression.Call(Expression.TypeAs(input, typeof(EntityReference)), + 4421193                typeof(EntityReference).GetMethod("get_Id"));1194 + 4421195            return Expression.Condition( + 4421196                Expression.TypeIs(input, typeof(EntityReference)),  //If input is an entity reference, compare the Guid  + 4421197                Expression.Convert( + 4421198                    getIdFromEntityReferenceExpr, + 4421199                    typeof(Guid)), + 4421200                Expression.Condition(Expression.TypeIs(input, typeof(Guid)),  //If any other case, then just compare it  + 4421201                    Expression.Convert(input, typeof(Guid)), + 4421202                    Expression.Constant(Guid.Empty, typeof(Guid))));1203 + 4541204        }12051206        protected static Expression GetAppropiateCastExpressionBasedOnDecimal(Expression input) + 321207        { + 321208            return Expression.Condition( + 321209                        Expression.TypeIs(input, typeof(Money)), + 321210                                Expression.Convert( + 321211                                    Expression.Call(Expression.TypeAs(input, typeof(Money)), + 321212                                            typeof(Money).GetMethod("get_Value")), + 321213                                            typeof(decimal)), + 321214                           Expression.Condition(Expression.TypeIs(input, typeof(decimal)), + 321215                                        Expression.Convert(input, typeof(decimal)), + 321216                                        Expression.Constant(0.0M)));1217 + 321218        }  12191220        protected static Expression TransformExpressionGetDateOnlyPart(Expression input) - 1801221        { - 1801222            return Expression.Call(input, typeof(DateTime).GetMethod("get_Date")); - 1801223        }12241225        protected static Expression TransformExpressionValueBasedOnOperator(ConditionOperator op, Expression input) - 50061226        { - 50061227             switch (op)1228            {1229                case ConditionOperator.Today:1230                case ConditionOperator.Yesterday:1231                case ConditionOperator.Tomorrow:1232                case ConditionOperator.On:1233                case ConditionOperator.OnOrAfter:1234                case ConditionOperator.OnOrBefore: - 1801235                    return TransformExpressionGetDateOnlyPart(input);12361237                default: - 48261238                    return input; //No transformation1239            } - 50061240        }12411242        protected static Expression TranslateConditionExpressionEqual(XrmFakedContext context, TypedConditionExpression  - 23831243        {1220        protected static Expression GetAppropiateCastExpressionBasedOnBoolean(Expression input) + 1561221        { + 1561222            return Expression.Condition( + 1561223                        Expression.TypeIs(input, typeof(BooleanManagedProperty)), + 1561224                                Expression.Convert( + 1561225                                    Expression.Call(Expression.TypeAs(input, typeof(BooleanManagedProperty)), + 1561226                                            typeof(BooleanManagedProperty).GetMethod("get_Value")), + 1561227                                            typeof(bool)), + 1561228                           Expression.Condition(Expression.TypeIs(input, typeof(bool)), + 1561229                                        Expression.Convert(input, typeof(bool)), + 1561230                                        Expression.Constant(false)));1231 + 1561232        }12331234        protected static Expression GetAppropiateCastExpressionBasedOnInt(Expression input) + 13941235        { + 13941236            return Expression.Condition( + 13941237                        Expression.TypeIs(input, typeof(OptionSetValue)), + 13941238                                            Expression.Convert( + 13941239                                                Expression.Call(Expression.TypeAs(input, typeof(OptionSetValue)), + 13941240                                                        typeof(OptionSetValue).GetMethod("get_Value")), + 13941241                                                        typeof(int)), + 13941242                                                    Expression.Convert(input, typeof(int))); + 13941243        }  1244 - 23831245            BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false));1246 - 23831247            object unaryOperatorValue = null;1248 - 23831249             switch (c.CondExpression.Operator)1250            {1251                case ConditionOperator.Today: - 121252                    unaryOperatorValue = DateTime.Today; - 121253                    break;1254                case ConditionOperator.Yesterday: - 121255                    unaryOperatorValue = DateTime.Today.AddDays(-1); - 121256                    break;1257                case ConditionOperator.Tomorrow: - 121258                    unaryOperatorValue = DateTime.Today.AddDays(1); - 121259                    break;1260                case ConditionOperator.EqualUserId:1261                case ConditionOperator.NotEqualUserId: - 121262                    unaryOperatorValue = context.CallerId.Id; - 121263                    break;12641265                case ConditionOperator.EqualBusinessId:1266                case ConditionOperator.NotEqualBusinessId: - 61267                    unaryOperatorValue = context.BusinessUnitId.Id; - 61268                    break;1269            }1270 - 23831271             if (unaryOperatorValue != null) - 541272            {1273                //c.Values empty in this case - 541274                var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(c.AttributeType, getAttributeValueEx - 541275                var transformedExpression = TransformExpressionValueBasedOnOperator(c.CondExpression.Operator, leftHandS1276 - 541277                expOrValues = Expression.Equal(transformedExpression, - 541278                                GetAppropiateTypedValueAndType(unaryOperatorValue, c.AttributeType)); - 541279            }1280#if FAKE_XRM_EASY_9 - 4001281             else if (c.AttributeType == typeof(OptionSetValueCollection)) - 91282            { - 91283                var conditionValue = GetSingleConditionValue(c);1284 - 61285                var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(c.AttributeType, getAttributeValueEx - 61286                var rightHandSideExpression = Expression.Constant(ConvertToHashSetOfInt(conditionValue, isOptionSetValue1287 - 51288                expOrValues = Expression.Equal( - 51289                    Expression.Call(leftHandSideExpression, typeof(HashSet<int>).GetMethod("SetEquals"), rightHandSideEx - 51290                    Expression.Constant(true)); - 51291            }1292#endif1293            else - 23201294            { - 116001295                foreach (object value in c.CondExpression.Values) - 23201296                { - 23201297                    var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(c.AttributeType, getAttributeVal - 23201298                    var transformedExpression = TransformExpressionValueBasedOnOperator(c.CondExpression.Operator, leftH1299 - 23201300                    expOrValues = Expression.Or(expOrValues, Expression.Equal( - 23201301                                transformedExpression, - 23201302                                TransformExpressionValueBasedOnOperator(c.CondExpression.Operator, GetAppropiateTypedVal13031304 - 23201305                } - 23201306            }1307 - 23791308            return Expression.AndAlso( - 23791309                            containsAttributeExpr, - 23791310                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), - 23791311                                expOrValues)); - 23791312        }13131314        private static object GetSingleConditionValue(TypedConditionExpression c) - 91315        { - 91316             if (c.CondExpression.Values.Count != 1) - 11317            { - 11318                OrganizationServiceFaultInvalidArgument.Throw($"The {c.CondExpression.Operator} requires 1 value/s, not  - 01319            }1245        protected static Expression GetAppropiateCastExpressionBasedOnOptionSetValueCollection(Expression input) + 681246        { + 681247            return Expression.Call(typeof(XrmFakedContext).GetMethod("ConvertToHashSetOfInt"), input, Expression.Constan + 681248        }12491250#if FAKE_XRM_EASY_91251        public static HashSet<int> ConvertToHashSetOfInt(object input, bool isOptionSetValueCollectionAccepted) + 1441252        { + 1441253            var set = new HashSet<int>();1254 + 1441255             var faultReason = $"The formatter threw an exception while trying to deserialize the message: There was an e + 1441256                $" http://schemas.microsoft.com/xrm/2011/Contracts/Services:query. The InnerException message was 'Error + 1441257                $"'http://schemas.microsoft.com/2003/10/Serialization/Arrays:anyType' contains data from a type that map + 1441258                $"'http://schemas.microsoft.com/xrm/2011/Contracts:{input?.GetType()}'. The deserializer has no knowledg + 1441259                $"Consider changing the implementation of the ResolveName method on your DataContractResolver to return  + 1441260                $"'{input?.GetType()}' and namespace 'http://schemas.microsoft.com/xrm/2011/Contracts'.'.  Please see In1261 + 1441262             if (input is int) + 41263            { + 41264                set.Add((int)input); + 41265            } + 1401266             else if (input is string) + 11267            { + 11268                set.Add(int.Parse(input as string)); + 11269            } + 1391270             else if (input is int[]) + 01271            { + 01272                set.UnionWith(input as int[]); + 01273            } + 1391274             else if (input is string[]) + 01275            { + 01276                set.UnionWith((input as string[]).Select(s => int.Parse(s))); + 01277            } + 1391278             else if (input is DataCollection<object>) + 281279            { + 281280                var collection = input as DataCollection<object>;1281 + 621282                 if (collection.All(o => o is int)) + 71283                { + 71284                    set.UnionWith(collection.Cast<int>()); + 71285                } + 491286                 else if (collection.All(o => o is string)) + 91287                { + 251288                    set.UnionWith(collection.Select(o => int.Parse(o as string))); + 91289                } + 121290                 else if (collection.Count == 1 && collection[0] is int[]) + 81291                { + 81292                    set.UnionWith(collection[0] as int[]); + 81293                } + 41294                 else if (collection.Count == 1 && collection[0] is string[]) + 01295                { + 01296                    set.UnionWith((collection[0] as string[]).Select(s => int.Parse(s))); + 01297                }1298                else + 41299                { + 41300                    throw new FaultException(new FaultReason(faultReason));1301                } + 241302            } + 1111303             else if (isOptionSetValueCollectionAccepted && input is OptionSetValueCollection) + 1101304            { + 3261305                set.UnionWith((input as OptionSetValueCollection).Select(osv => osv.Value)); + 1101306            }1307            else + 11308            { + 11309                throw new FaultException(new FaultReason(faultReason));1310            }1311 + 1391312            return set; + 1391313        }1314#endif13151316        protected static Expression TransformExpressionGetDateOnlyPart(Expression input) + 1801317        { + 1801318            return Expression.Call(input, typeof(DateTime).GetMethod("get_Date")); + 1801319        }  1320 - 81321            var conditionValue = c.CondExpression.Values.Single();1322 - 81323             if (!(conditionValue is string) && conditionValue is IEnumerable) - 41324            { - 41325                var conditionValueEnumerable = conditionValue as IEnumerable; - 41326                var count = 0;1327 - 261328                foreach (var obj in conditionValueEnumerable) - 71329                { - 71330                    count++; - 71331                    conditionValue = obj; - 71332                }1333 - 41334                 if (count != 1) - 21335                { - 21336                    OrganizationServiceFaultInvalidArgument.Throw($"The {c.CondExpression.Operator} requires 1 value/s,  - 01337                } - 21338            }1339 - 61340            return conditionValue; - 61341        }1321        protected static Expression TransformExpressionValueBasedOnOperator(ConditionOperator op, Expression input) + 50461322        { + 50461323             switch (op)1324            {1325                case ConditionOperator.Today:1326                case ConditionOperator.Yesterday:1327                case ConditionOperator.Tomorrow:1328                case ConditionOperator.On:1329                case ConditionOperator.OnOrAfter:1330                case ConditionOperator.OnOrBefore: + 1801331                    return TransformExpressionGetDateOnlyPart(input);13321333                default: + 48661334                    return input; //No transformation1335            } + 50461336        }13371338        protected static Expression TranslateConditionExpressionEqual(XrmFakedContext context, TypedConditionExpression  + 24031339        {1340 + 24031341            BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false));  13421343        protected static Expression TranslateConditionExpressionIn(TypedConditionExpression tc, Expression getAttributeV - 321344        { - 321345            var c = tc.CondExpression;1346 - 321347            BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false));13481349#if FAKE_XRM_EASY_9 - 171350             if (tc.AttributeType == typeof(OptionSetValueCollection)) - 141351            { - 141352                var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueE - 141353                var rightHandSideExpression = Expression.Constant(ConvertToHashSetOfInt(c.Values, isOptionSetValueCollec1354 - 121355                expOrValues = Expression.Equal( - 121356                    Expression.Call(leftHandSideExpression, typeof(HashSet<int>).GetMethod("SetEquals"), rightHandSideEx - 121357                    Expression.Constant(true)); - 121358            }1359            else1360#endif - 181361            { - 1021362                foreach (object value in c.Values) - 241363                { - 241364                     if (value is Array) - 121365                    { - 1081366                        foreach (var a in ((Array)value)) - 361367                        { - 361368                            expOrValues = Expression.Or(expOrValues, Expression.Equal( - 361369                                GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, a), - 361370                                GetAppropiateTypedValueAndType(a, tc.AttributeType))); - 361371                        } - 121372                    }1373                    else - 121374                    { - 121375                        expOrValues = Expression.Or(expOrValues, Expression.Equal( - 121376                                    GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, valu - 121377                                    GetAppropiateTypedValueAndType(value, tc.AttributeType))); - 121378                    } - 241379                } - 181380            }1381 - 301382            return Expression.AndAlso( - 301383                            containsAttributeExpr, - 301384                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), - 301385                                expOrValues)); - 301386        }13871388        //protected static Expression TranslateConditionExpressionOn(ConditionExpression c, Expression getAttributeValue1389        //{1390        //    BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false));1391        //    foreach (object value in c.Values)1392        //    {13931394        //        expOrValues = Expression.Or(expOrValues, Expression.Equal(1395        //                    GetAppropiateCastExpressionBasedOnValue(getAttributeValueExpr, value),1396        //                    GetAppropiateTypedValue(value)));139713981399        //    }1400        //    return Expression.AndAlso(1401        //                    containsAttributeExpr,1402        //                    Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)),1403        //                        expOrValues));1404        //}14051406        protected static Expression TranslateConditionExpressionGreaterThanOrEqual(XrmFakedContext context, TypedConditi - 381407        {1408            //var c = tc.CondExpression; + 24031343            object unaryOperatorValue = null;1344 + 24031345             switch (c.CondExpression.Operator)1346            {1347                case ConditionOperator.Today: + 121348                    unaryOperatorValue = DateTime.Today; + 121349                    break;1350                case ConditionOperator.Yesterday: + 121351                    unaryOperatorValue = DateTime.Today.AddDays(-1); + 121352                    break;1353                case ConditionOperator.Tomorrow: + 121354                    unaryOperatorValue = DateTime.Today.AddDays(1); + 121355                    break;1356                case ConditionOperator.EqualUserId:1357                case ConditionOperator.NotEqualUserId: + 121358                    unaryOperatorValue = context.CallerId.Id; + 121359                    break;13601361                case ConditionOperator.EqualBusinessId:1362                case ConditionOperator.NotEqualBusinessId: + 61363                    unaryOperatorValue = context.BusinessUnitId.Id; + 61364                    break;1365            }1366 + 24031367             if (unaryOperatorValue != null) + 541368            {1369                //c.Values empty in this case + 541370                var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(c.AttributeType, getAttributeValueEx + 541371                var transformedExpression = TransformExpressionValueBasedOnOperator(c.CondExpression.Operator, leftHandS1372 + 541373                expOrValues = Expression.Equal(transformedExpression, + 541374                                GetAppropiateTypedValueAndType(unaryOperatorValue, c.AttributeType)); + 541375            }1376#if FAKE_XRM_EASY_9 + 4041377             else if (c.AttributeType == typeof(OptionSetValueCollection)) + 91378            { + 91379                var conditionValue = GetSingleConditionValue(c);1380 + 61381                var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(c.AttributeType, getAttributeValueEx + 61382                var rightHandSideExpression = Expression.Constant(ConvertToHashSetOfInt(conditionValue, isOptionSetValue1383 + 51384                expOrValues = Expression.Equal( + 51385                    Expression.Call(leftHandSideExpression, typeof(HashSet<int>).GetMethod("SetEquals"), rightHandSideEx + 51386                    Expression.Constant(true)); + 51387            }1388#endif1389            else + 23401390            { + 117001391                foreach (object value in c.CondExpression.Values) + 23401392                { + 23401393                    var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(c.AttributeType, getAttributeVal + 23401394                    var transformedExpression = TransformExpressionValueBasedOnOperator(c.CondExpression.Operator, leftH1395 + 23401396                    expOrValues = Expression.Or(expOrValues, Expression.Equal( + 23401397                                transformedExpression, + 23401398                                TransformExpressionValueBasedOnOperator(c.CondExpression.Operator, GetAppropiateTypedVal13991400 + 23401401                } + 23401402            }1403 + 23991404            return Expression.AndAlso( + 23991405                            containsAttributeExpr, + 23991406                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), + 23991407                                expOrValues)); + 23991408        }  1409 - 381410            return Expression.Or( - 381411                                TranslateConditionExpressionEqual(context, tc, getAttributeValueExpr, containsAttributeE - 381412                                TranslateConditionExpressionGreaterThan(tc, getAttributeValueExpr, containsAttributeExpr1413 - 381414        }1415        protected static Expression TranslateConditionExpressionGreaterThan(TypedConditionExpression tc, Expression getA - 741416        { - 741417            var c = tc.CondExpression;1410        private static object GetSingleConditionValue(TypedConditionExpression c) + 91411        { + 91412             if (c.CondExpression.Values.Count != 1) + 11413            { + 11414                OrganizationServiceFaultInvalidArgument.Throw($"The {c.CondExpression.Operator} requires 1 value/s, not  + 01415            }1416 + 81417            var conditionValue = c.CondExpression.Values.Single();  1418 - 1481419             if (c.Values.Count(v => v != null) != 1) - 01420            { - 01421                throw new FaultException(new FaultReason($"The ConditonOperator.{c.Operator} requires 1 value/s, not {c.1422            } + 81419             if (!(conditionValue is string) && conditionValue is IEnumerable) + 41420            { + 41421                var conditionValueEnumerable = conditionValue as IEnumerable; + 41422                var count = 0;  1423 - 741424             if (tc.AttributeType == typeof(string)) - 181425            { - 181426                return TranslateConditionExpressionGreaterThanString(tc, getAttributeValueExpr, containsAttributeExpr);1427            } - 561428             else if (GetAppropiateTypeForValue(c.Values[0]) == typeof(string)) - 01429            { - 01430                return TranslateConditionExpressionGreaterThanString(tc, getAttributeValueExpr, containsAttributeExpr);1431            }1432            else - 561433            { - 561434                BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false)); - 2801435                foreach (object value in c.Values) - 561436                { - 561437                    var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeVa - 561438                    var transformedExpression = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, left1439 - 561440                    expOrValues = Expression.Or(expOrValues, - 561441                            Expression.GreaterThan( - 561442                                transformedExpression, - 561443                                TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, GetAppropiateTypedVa - 561444                } - 561445                return Expression.AndAlso( - 561446                                containsAttributeExpr, - 561447                                Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)) - 561448                                    expOrValues));1449            } + 261424                foreach (var obj in conditionValueEnumerable) + 71425                { + 71426                    count++; + 71427                    conditionValue = obj; + 71428                }1429 + 41430                 if (count != 1) + 21431                { + 21432                    OrganizationServiceFaultInvalidArgument.Throw($"The {c.CondExpression.Operator} requires 1 value/s,  + 01433                } + 21434            }1435 + 61436            return conditionValue; + 61437        }14381439        protected static Expression TranslateConditionExpressionIn(TypedConditionExpression tc, Expression getAttributeV + 321440        { + 321441            var c = tc.CondExpression;1442 + 321443            BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false));14441445#if FAKE_XRM_EASY_9 + 171446             if (tc.AttributeType == typeof(OptionSetValueCollection)) + 141447            { + 141448                var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueE + 141449                var rightHandSideExpression = Expression.Constant(ConvertToHashSetOfInt(c.Values, isOptionSetValueCollec  1450 - 741451        }14521453        protected static Expression TranslateConditionExpressionGreaterThanString(TypedConditionExpression tc, Expressio - 181454        { - 181455            var c = tc.CondExpression;1456 - 181457            BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false)); - 901458            foreach (object value in c.Values) - 181459            { - 181460                var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueE - 181461                var transformedExpression = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, leftHand1462 - 181463                var left = transformedExpression; - 181464                var right = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, GetAppropiateTypedValueA1465 - 181466                var methodCallExpr = GetCompareToExpression<string>(left, right);1467 - 181468                expOrValues = Expression.Or(expOrValues, - 181469                        Expression.GreaterThan( - 181470                            methodCallExpr, - 181471                            Expression.Constant(0))); - 181472            } - 181473            return Expression.AndAlso( - 181474                            containsAttributeExpr, - 181475                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), - 181476                                expOrValues)); - 181477        }14781479        protected static Expression TranslateConditionExpressionLessThanOrEqual(XrmFakedContext context, TypedConditionE - 281480        {1481            //var c = tc.CondExpression;1482 - 281483            return Expression.Or( - 281484                                TranslateConditionExpressionEqual(context, tc, getAttributeValueExpr, containsAttributeE - 281485                                TranslateConditionExpressionLessThan(tc, getAttributeValueExpr, containsAttributeExpr));1486 - 281487        }14881489        protected static Expression GetCompareToExpression<T>(Expression left, Expression right) - 481490        { - 481491            return Expression.Call(left, typeof(T).GetMethod("CompareTo", new Type[] { typeof(string) }), new[] { right  - 481492        } + 121451                expOrValues = Expression.Equal( + 121452                    Expression.Call(leftHandSideExpression, typeof(HashSet<int>).GetMethod("SetEquals"), rightHandSideEx + 121453                    Expression.Constant(true)); + 121454            }1455            else1456#endif + 181457            { + 1021458                foreach (object value in c.Values) + 241459                { + 241460                     if (value is Array) + 121461                    { + 1081462                        foreach (var a in ((Array)value)) + 361463                        { + 361464                            expOrValues = Expression.Or(expOrValues, Expression.Equal( + 361465                                GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, a), + 361466                                GetAppropiateTypedValueAndType(a, tc.AttributeType))); + 361467                        } + 121468                    }1469                    else + 121470                    { + 121471                        expOrValues = Expression.Or(expOrValues, Expression.Equal( + 121472                                    GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, valu + 121473                                    GetAppropiateTypedValueAndType(value, tc.AttributeType))); + 121474                    } + 241475                } + 181476            }1477 + 301478            return Expression.AndAlso( + 301479                            containsAttributeExpr, + 301480                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), + 301481                                expOrValues)); + 301482        }14831484        //protected static Expression TranslateConditionExpressionOn(ConditionExpression c, Expression getAttributeValue1485        //{1486        //    BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false));1487        //    foreach (object value in c.Values)1488        //    {14891490        //        expOrValues = Expression.Or(expOrValues, Expression.Equal(1491        //                    GetAppropiateCastExpressionBasedOnValue(getAttributeValueExpr, value),1492        //                    GetAppropiateTypedValue(value)));  14931494        protected static Expression TranslateConditionExpressionLessThanString(TypedConditionExpression tc, Expression g - 301495        { - 301496            var c = tc.CondExpression;1497 - 301498            BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false)); - 1501499            foreach (object value in c.Values) - 301500            { - 301501                var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueE - 301502                var transformedLeftHandSideExpression = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operat1503 - 301504                var rightHandSideExpression = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, GetApp14941495        //    }1496        //    return Expression.AndAlso(1497        //                    containsAttributeExpr,1498        //                    Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)),1499        //                        expOrValues));1500        //}15011502        protected static Expression TranslateConditionExpressionGreaterThanOrEqual(XrmFakedContext context, TypedConditi + 381503        {1504            //var c = tc.CondExpression;  15051506                //var compareToMethodCall = Expression.Call(transformedLeftHandSideExpression, typeof(string).GetMethod( - 301507                var compareToMethodCall = GetCompareToExpression<string>(transformedLeftHandSideExpression, rightHandSid1508 - 301509                expOrValues = Expression.Or(expOrValues, - 301510                        Expression.LessThan(compareToMethodCall, Expression.Constant(0))); - 301511            } - 301512            return Expression.AndAlso( - 301513                            containsAttributeExpr, - 301514                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), - 301515                                expOrValues)); - 301516        }15171518        protected static Expression TranslateConditionExpressionLessThan(TypedConditionExpression tc, Expression getAttr - 821519        { - 821520            var c = tc.CondExpression;1521 - 1641522             if (c.Values.Count(v => v != null) != 1) - 01523            { - 01524                throw new FaultException(new FaultReason($"The ConditonOperator.{c.Operator} requires 1 value/s, not {c.1525            }1526 - 821527             if (tc.AttributeType == typeof(string)) - 241528            { - 241529                return TranslateConditionExpressionLessThanString(tc, getAttributeValueExpr, containsAttributeExpr);1530            } - 581531             else if (GetAppropiateTypeForValue(c.Values[0]) == typeof(string)) - 61532            { - 61533                return TranslateConditionExpressionLessThanString(tc, getAttributeValueExpr, containsAttributeExpr);1534            }1535            else - 521536            { - 521537                BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false)); - 2601538                foreach (object value in c.Values) - 521539                { - 521540                    var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeVa - 521541                    var transformedExpression = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, left1542 - 521543                    expOrValues = Expression.Or(expOrValues, - 521544                            Expression.LessThan( - 521545                                transformedExpression, - 521546                                TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, GetAppropiateTypedVa - 521547                } - 521548                return Expression.AndAlso( - 521549                                containsAttributeExpr, - 521550                                Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)) - 521551                                    expOrValues));1552            }1553 - 821554        }15551556        protected static Expression TranslateConditionExpressionLast(TypedConditionExpression tc, Expression getAttribut - 61557        { - 61558            var c = tc.CondExpression;1559 - 61560            var beforeDateTime = default(DateTime); - 61561            var currentDateTime = DateTime.UtcNow;1562 - 61563             switch (c.Operator)1564            {1565                case ConditionOperator.Last7Days: - 61566                    beforeDateTime = currentDateTime.AddDays(-7); - 61567                    break;1568            }1569 - 61570            c.Values.Add(beforeDateTime); - 61571            c.Values.Add(currentDateTime);1572 - 61573            return TranslateConditionExpressionBetween(tc, getAttributeValueExpr, containsAttributeExpr); - 61574        }15751576        /// <summary>1577        /// Takes a condition expression which needs translating into a 'between two dates' expression and works out the1578        /// </summary>1579        protected static Expression TranslateConditionExpressionBetweenDates(TypedConditionExpression tc, Expression get - 541580        { - 541581            var c = tc.CondExpression; + 381506            return Expression.Or( + 381507                                TranslateConditionExpressionEqual(context, tc, getAttributeValueExpr, containsAttributeE + 381508                                TranslateConditionExpressionGreaterThan(tc, getAttributeValueExpr, containsAttributeExpr1509 + 381510        }1511        protected static Expression TranslateConditionExpressionGreaterThan(TypedConditionExpression tc, Expression getA + 741512        { + 741513            var c = tc.CondExpression;1514 + 1481515             if (c.Values.Count(v => v != null) != 1) + 01516            { + 01517                throw new FaultException(new FaultReason($"The ConditonOperator.{c.Operator} requires 1 value/s, not {c.1518            }1519 + 741520             if (tc.AttributeType == typeof(string)) + 181521            { + 181522                return TranslateConditionExpressionGreaterThanString(tc, getAttributeValueExpr, containsAttributeExpr);1523            } + 561524             else if (GetAppropiateTypeForValue(c.Values[0]) == typeof(string)) + 01525            { + 01526                return TranslateConditionExpressionGreaterThanString(tc, getAttributeValueExpr, containsAttributeExpr);1527            }1528            else + 561529            { + 561530                BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false)); + 2801531                foreach (object value in c.Values) + 561532                { + 561533                    var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeVa + 561534                    var transformedExpression = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, left1535 + 561536                    expOrValues = Expression.Or(expOrValues, + 561537                            Expression.GreaterThan( + 561538                                transformedExpression, + 561539                                TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, GetAppropiateTypedVa + 561540                } + 561541                return Expression.AndAlso( + 561542                                containsAttributeExpr, + 561543                                Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)) + 561544                                    expOrValues));1545            }1546 + 741547        }15481549        protected static Expression TranslateConditionExpressionGreaterThanString(TypedConditionExpression tc, Expressio + 181550        { + 181551            var c = tc.CondExpression;1552 + 181553            BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false)); + 901554            foreach (object value in c.Values) + 181555            { + 181556                var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueE + 181557                var transformedExpression = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, leftHand1558 + 181559                var left = transformedExpression; + 181560                var right = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, GetAppropiateTypedValueA1561 + 181562                var methodCallExpr = GetCompareToExpression<string>(left, right);1563 + 181564                expOrValues = Expression.Or(expOrValues, + 181565                        Expression.GreaterThan( + 181566                            methodCallExpr, + 181567                            Expression.Constant(0))); + 181568            } + 181569            return Expression.AndAlso( + 181570                            containsAttributeExpr, + 181571                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), + 181572                                expOrValues)); + 181573        }15741575        protected static Expression TranslateConditionExpressionLessThanOrEqual(XrmFakedContext context, TypedConditionE + 281576        {1577            //var c = tc.CondExpression;1578 + 281579            return Expression.Or( + 281580                                TranslateConditionExpressionEqual(context, tc, getAttributeValueExpr, containsAttributeE + 281581                                TranslateConditionExpressionLessThan(tc, getAttributeValueExpr, containsAttributeExpr));  1582 - 541583            DateTime? fromDate = null; - 541584            DateTime? toDate = null;1585 - 541586            var today = DateTime.Today; - 541587            var thisYear = today.Year; - 541588            var thisMonth = today.Month; + 281583        }15841585        protected static Expression GetCompareToExpression<T>(Expression left, Expression right) + 481586        { + 481587            return Expression.Call(left, typeof(T).GetMethod("CompareTo", new Type[] { typeof(string) }), new[] { right  + 481588        }  1589 - 541590             switch (c.Operator)1591            {1592                case ConditionOperator.ThisYear: // From first day of this year to last day of this year - 61593                    fromDate = new DateTime(thisYear, 1, 1); - 61594                    toDate = new DateTime(thisYear, 12, 31); - 61595                    break;1596                case ConditionOperator.LastYear: // From first day of last year to last day of last year - 61597                    fromDate = new DateTime(thisYear - 1, 1, 1); - 61598                    toDate = new DateTime(thisYear - 1, 12, 31); - 61599                    break;1600                case ConditionOperator.NextYear: // From first day of next year to last day of next year - 61601                    fromDate = new DateTime(thisYear + 1, 1, 1); - 61602                    toDate = new DateTime(thisYear + 1, 12, 31); - 61603                    break;1604                case ConditionOperator.ThisMonth: // From first day of this month to last day of this month - 61605                    fromDate = new DateTime(thisYear, thisMonth, 1);1606                    // Last day of this month: Add one month to the first of this month, and then remove one day - 61607                    toDate = new DateTime(thisYear, thisMonth, 1).AddMonths(1).AddDays(-1); - 61608                    break;1609                case ConditionOperator.LastMonth: // From first day of last month to last day of last month - 61610                    fromDate = new DateTime(thisYear, thisMonth, 1).AddMonths(-1);1611                    // Last day of last month: One day before the first of this month - 61612                    toDate = new DateTime(thisYear, thisMonth, 1).AddDays(-1); - 61613                    break;1614                case ConditionOperator.NextMonth: // From first day of next month to last day of next month - 61615                    fromDate = new DateTime(thisYear, thisMonth, 1).AddMonths(1);1616                    // LAst day of Next Month: Add two months to the first of this month, and then go back one day - 61617                    toDate = new DateTime(thisYear, thisMonth, 1).AddMonths(2).AddDays(-1); - 61618                    break;1619                case ConditionOperator.ThisWeek: - 61620                    fromDate = today.ToFirstDayOfDeltaWeek(); - 61621                    toDate = today.ToLastDayOfDeltaWeek().AddDays(1); - 61622                    break;1623                case ConditionOperator.LastWeek: - 61624                    fromDate = today.ToFirstDayOfDeltaWeek(-1); - 61625                    toDate = today.ToLastDayOfDeltaWeek(-1).AddDays(1); - 61626                    break;1627                case ConditionOperator.NextWeek: - 61628                    fromDate = today.ToFirstDayOfDeltaWeek(1); - 61629                    toDate = today.ToLastDayOfDeltaWeek(1).AddDays(1); - 61630                    break;1631            }1632 - 541633            c.Values.Add(fromDate); - 541634            c.Values.Add(toDate);1635 - 541636            return TranslateConditionExpressionBetween(tc, getAttributeValueExpr, containsAttributeExpr); - 541637        }1590        protected static Expression TranslateConditionExpressionLessThanString(TypedConditionExpression tc, Expression g + 301591        { + 301592            var c = tc.CondExpression;1593 + 301594            BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false)); + 1501595            foreach (object value in c.Values) + 301596            { + 301597                var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueE + 301598                var transformedLeftHandSideExpression = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operat1599 + 301600                var rightHandSideExpression = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, GetApp16011602                //var compareToMethodCall = Expression.Call(transformedLeftHandSideExpression, typeof(string).GetMethod( + 301603                var compareToMethodCall = GetCompareToExpression<string>(transformedLeftHandSideExpression, rightHandSid1604 + 301605                expOrValues = Expression.Or(expOrValues, + 301606                        Expression.LessThan(compareToMethodCall, Expression.Constant(0))); + 301607            } + 301608            return Expression.AndAlso( + 301609                            containsAttributeExpr, + 301610                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), + 301611                                expOrValues)); + 301612        }16131614        protected static Expression TranslateConditionExpressionLessThan(TypedConditionExpression tc, Expression getAttr + 821615        { + 821616            var c = tc.CondExpression;1617 + 1641618             if (c.Values.Count(v => v != null) != 1) + 01619            { + 01620                throw new FaultException(new FaultReason($"The ConditonOperator.{c.Operator} requires 1 value/s, not {c.1621            }1622 + 821623             if (tc.AttributeType == typeof(string)) + 241624            { + 241625                return TranslateConditionExpressionLessThanString(tc, getAttributeValueExpr, containsAttributeExpr);1626            } + 581627             else if (GetAppropiateTypeForValue(c.Values[0]) == typeof(string)) + 61628            { + 61629                return TranslateConditionExpressionLessThanString(tc, getAttributeValueExpr, containsAttributeExpr);1630            }1631            else + 521632            { + 521633                BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false)); + 2601634                foreach (object value in c.Values) + 521635                { + 521636                    var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeVa + 521637                    var transformedExpression = TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, left  16381639        protected static Expression TranslateConditionExpressionBetween(TypedConditionExpression tc, Expression getAttri - 841640        { - 841641            var c = tc.CondExpression;16421643            object value1, value2; - 841644            value1 = c.Values[0]; - 841645            value2 = c.Values[1];16461647            //Between the range... - 841648            var exp = Expression.And( - 841649                Expression.GreaterThanOrEqual( - 841650                            GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, value1), - 841651                            GetAppropiateTypedValueAndType(value1, tc.AttributeType)), - 841652 - 841653                Expression.LessThanOrEqual( - 841654                            GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, value2), - 841655                            GetAppropiateTypedValueAndType(value2, tc.AttributeType)));165616571658            //and... attribute exists too - 841659            return Expression.AndAlso( - 841660                            containsAttributeExpr, - 841661                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), - 841662                                exp)); - 841663        }16641665        protected static Expression TranslateConditionExpressionNull(TypedConditionExpression tc, Expression getAttribut - 1311666        { - 1311667            var c = tc.CondExpression; + 521639                    expOrValues = Expression.Or(expOrValues, + 521640                            Expression.LessThan( + 521641                                transformedExpression, + 521642                                TransformExpressionValueBasedOnOperator(tc.CondExpression.Operator, GetAppropiateTypedVa + 521643                } + 521644                return Expression.AndAlso( + 521645                                containsAttributeExpr, + 521646                                Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)) + 521647                                    expOrValues));1648            }1649 + 821650        }16511652        protected static Expression TranslateConditionExpressionLast(TypedConditionExpression tc, Expression getAttribut + 61653        { + 61654            var c = tc.CondExpression;1655 + 61656            var beforeDateTime = default(DateTime); + 61657            var currentDateTime = DateTime.UtcNow;1658 + 61659             switch (c.Operator)1660            {1661                case ConditionOperator.Last7Days: + 61662                    beforeDateTime = currentDateTime.AddDays(-7); + 61663                    break;1664            }1665 + 61666            c.Values.Add(beforeDateTime); + 61667            c.Values.Add(currentDateTime);  1668 - 1311669            return Expression.Or(Expression.AndAlso( - 1311670                                    containsAttributeExpr, - 1311671                                    Expression.Equal( - 1311672                                    getAttributeValueExpr, - 1311673                                    Expression.Constant(null))),   //Attribute is null - 1311674                                 Expression.AndAlso( - 1311675                                    Expression.Not(containsAttributeExpr), - 1311676                                    Expression.Constant(true)));   //Or attribute is not defined (null) - 1311677        } + 61669            return TranslateConditionExpressionBetween(tc, getAttributeValueExpr, containsAttributeExpr); + 61670        }16711672        /// <summary>1673        /// Takes a condition expression which needs translating into a 'between two dates' expression and works out the1674        /// </summary>1675        protected static Expression TranslateConditionExpressionBetweenDates(TypedConditionExpression tc, Expression get + 541676        { + 541677            var c = tc.CondExpression;  16781679        protected static Expression TranslateConditionExpressionOlderThan(TypedConditionExpression tc, Expression getAtt - 121680        { - 121681            var lessThanExpression = Expression.LessThan( - 121682                            GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, olderThanDat - 121683                            GetAppropiateTypedValueAndType(olderThanDate, tc.AttributeType));1684 - 121685            return Expression.AndAlso(containsAttributeExpr, - 121686                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), - 121687                                lessThanExpression)); - 121688        }16891690        protected static Expression TranslateConditionExpressionEndsWith(TypedConditionExpression tc, Expression getAttr - 181691        { - 181692            var c = tc.CondExpression;16931694            //Append a ´%´at the end of each condition value - 361695            var computedCondition = new ConditionExpression(c.AttributeName, c.Operator, c.Values.Select(x => "%" + x.To - 181696            var typedComputedCondition = new TypedConditionExpression(computedCondition); - 181697            typedComputedCondition.AttributeType = tc.AttributeType;1698 - 181699            return TranslateConditionExpressionLike(typedComputedCondition, getAttributeValueExpr, containsAttributeExpr - 181700        }17011702        protected static Expression GetToStringExpression<T>(Expression e) - 521703        { - 521704            return Expression.Call(e, typeof(T).GetMethod("ToString", new Type[] { })); - 521705        }1706        protected static Expression GetCaseInsensitiveExpression(Expression e) - 25951707        { - 25951708            return Expression.Call(e, - 25951709                                typeof(string).GetMethod("ToLowerInvariant", new Type[] { })); - 25951710        }17111712        protected static Expression TranslateConditionExpressionLike(TypedConditionExpression tc, Expression getAttribut - 1081713        { - 1081714            var c = tc.CondExpression;1715 - 1081716            BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false)); - 1081717            Expression convertedValueToStr = Expression.Convert(GetAppropiateCastExpressionBasedOnType(tc.AttributeType,1718 - 1081719            Expression convertedValueToStrAndToLower = GetCaseInsensitiveExpression(convertedValueToStr);1720 - 1081721            string sLikeOperator = "%"; - 5401722            foreach (object value in c.Values) - 1081723            { - 1081724                var strValue = value.ToString(); - 1081725                string sMethod = "";1726 - 1081727                 if (strValue.EndsWith(sLikeOperator) && strValue.StartsWith(sLikeOperator)) - 361728                    sMethod = "Contains";1729 - 721730                 else if (strValue.StartsWith(sLikeOperator)) - 181731                    sMethod = "EndsWith";17321733                else - 541734                    sMethod = "StartsWith";1735 - 1081736                expOrValues = Expression.Or(expOrValues, Expression.Call( - 1081737                    convertedValueToStrAndToLower, - 1081738                    typeof(string).GetMethod(sMethod, new Type[] { typeof(string) }), - 1081739                    Expression.Constant(value.ToString().ToLowerInvariant().Replace("%", "")) //Linq2CRM adds the percen - 1081740                )); - 1081741            } + 541679            DateTime? fromDate = null; + 541680            DateTime? toDate = null;1681 + 541682            var today = DateTime.Today; + 541683            var thisYear = today.Year; + 541684            var thisMonth = today.Month;1685 + 541686             switch (c.Operator)1687            {1688                case ConditionOperator.ThisYear: // From first day of this year to last day of this year + 61689                    fromDate = new DateTime(thisYear, 1, 1); + 61690                    toDate = new DateTime(thisYear, 12, 31); + 61691                    break;1692                case ConditionOperator.LastYear: // From first day of last year to last day of last year + 61693                    fromDate = new DateTime(thisYear - 1, 1, 1); + 61694                    toDate = new DateTime(thisYear - 1, 12, 31); + 61695                    break;1696                case ConditionOperator.NextYear: // From first day of next year to last day of next year + 61697                    fromDate = new DateTime(thisYear + 1, 1, 1); + 61698                    toDate = new DateTime(thisYear + 1, 12, 31); + 61699                    break;1700                case ConditionOperator.ThisMonth: // From first day of this month to last day of this month + 61701                    fromDate = new DateTime(thisYear, thisMonth, 1);1702                    // Last day of this month: Add one month to the first of this month, and then remove one day + 61703                    toDate = new DateTime(thisYear, thisMonth, 1).AddMonths(1).AddDays(-1); + 61704                    break;1705                case ConditionOperator.LastMonth: // From first day of last month to last day of last month + 61706                    fromDate = new DateTime(thisYear, thisMonth, 1).AddMonths(-1);1707                    // Last day of last month: One day before the first of this month + 61708                    toDate = new DateTime(thisYear, thisMonth, 1).AddDays(-1); + 61709                    break;1710                case ConditionOperator.NextMonth: // From first day of next month to last day of next month + 61711                    fromDate = new DateTime(thisYear, thisMonth, 1).AddMonths(1);1712                    // LAst day of Next Month: Add two months to the first of this month, and then go back one day + 61713                    toDate = new DateTime(thisYear, thisMonth, 1).AddMonths(2).AddDays(-1); + 61714                    break;1715                case ConditionOperator.ThisWeek: + 61716                    fromDate = today.ToFirstDayOfDeltaWeek(); + 61717                    toDate = today.ToLastDayOfDeltaWeek().AddDays(1); + 61718                    break;1719                case ConditionOperator.LastWeek: + 61720                    fromDate = today.ToFirstDayOfDeltaWeek(-1); + 61721                    toDate = today.ToLastDayOfDeltaWeek(-1).AddDays(1); + 61722                    break;1723                case ConditionOperator.NextWeek: + 61724                    fromDate = today.ToFirstDayOfDeltaWeek(1); + 61725                    toDate = today.ToLastDayOfDeltaWeek(1).AddDays(1); + 61726                    break;1727            }1728 + 541729            c.Values.Add(fromDate); + 541730            c.Values.Add(toDate);1731 + 541732            return TranslateConditionExpressionBetween(tc, getAttributeValueExpr, containsAttributeExpr); + 541733        }17341735        protected static Expression TranslateConditionExpressionBetween(TypedConditionExpression tc, Expression getAttri + 841736        { + 841737            var c = tc.CondExpression;17381739            object value1, value2; + 841740            value1 = c.Values[0]; + 841741            value2 = c.Values[1];  1742 - 1081743            return Expression.AndAlso( - 1081744                            containsAttributeExpr, - 1081745                            expOrValues); - 1081746        }17471748        protected static Expression TranslateConditionExpressionContains(TypedConditionExpression tc, Expression getAttr - 241749        { - 241750            var c = tc.CondExpression;17511752            //Append a ´%´at the end of each condition value - 481753            var computedCondition = new ConditionExpression(c.AttributeName, c.Operator, c.Values.Select(x => "%" + x.To - 241754            var computedTypedCondition = new TypedConditionExpression(computedCondition); - 241755            computedTypedCondition.AttributeType = tc.AttributeType;1756 - 241757            return TranslateConditionExpressionLike(computedTypedCondition, getAttributeValueExpr, containsAttributeExpr1758 - 241759        }1743            //Between the range... + 841744            var exp = Expression.And( + 841745                Expression.GreaterThanOrEqual( + 841746                            GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, value1), + 841747                            GetAppropiateTypedValueAndType(value1, tc.AttributeType)), + 841748 + 841749                Expression.LessThanOrEqual( + 841750                            GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, value2), + 841751                            GetAppropiateTypedValueAndType(value2, tc.AttributeType)));175217531754            //and... attribute exists too + 841755            return Expression.AndAlso( + 841756                            containsAttributeExpr, + 841757                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), + 841758                                exp)); + 841759        }  17601761        protected static BinaryExpression TranslateMultipleConditionExpressions(QueryExpression qe, XrmFakedContext cont - 21681762        { - 21681763            BinaryExpression binaryExpression = null;  //Default initialisation depending on logical operator - 21681764             if (op == LogicalOperator.And) - 21321765                binaryExpression = Expression.And(Expression.Constant(true), Expression.Constant(true));1766            else - 361767                binaryExpression = Expression.Or(Expression.Constant(false), Expression.Constant(false));1768 - 121691769            foreach (var c in conditions) - 28491770            {1771                //Create a new typed expression - 28491772                var typedExpression = new TypedConditionExpression(c); - 28491773                typedExpression.IsOuter = bIsOuter;1761        protected static Expression TranslateConditionExpressionNull(TypedConditionExpression tc, Expression getAttribut + 1791762        { + 1791763            var c = tc.CondExpression;1764 + 1791765            return Expression.Or(Expression.AndAlso( + 1791766                                    containsAttributeExpr, + 1791767                                    Expression.Equal( + 1791768                                    getAttributeValueExpr, + 1791769                                    Expression.Constant(null))),   //Attribute is null + 1791770                                 Expression.AndAlso( + 1791771                                    Expression.Not(containsAttributeExpr), + 1791772                                    Expression.Constant(true)));   //Or attribute is not defined (null) + 1791773        }  1774 - 28491775                string sAttributeName = c.AttributeName;17761777                //Find the attribute type if using early bound entities - 28491778                 if (context.ProxyTypesAssembly != null) - 22491779                {1775        protected static Expression TranslateConditionExpressionOlderThan(TypedConditionExpression tc, Expression getAtt + 121776        { + 121777            var lessThanExpression = Expression.LessThan( + 121778                            GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, olderThanDat + 121779                            GetAppropiateTypedValueAndType(olderThanDate, tc.AttributeType));  17801781#if FAKE_XRM_EASY_2013 || FAKE_XRM_EASY_2015 || FAKE_XRM_EASY_2016 || FAKE_XRM_EASY_365 || FAKE_XRM_EASY_9 - 18901782                     if (c.EntityName != null) - 751783                        sEntityName = qe.GetEntityNameFromAlias(c.EntityName);1784                    else - 18151785                    { - 18151786                         if (c.AttributeName.IndexOf(".") >= 0) - 3051787                        { - 3051788                            var alias = c.AttributeName.Split('.')[0]; - 3051789                            sEntityName = qe.GetEntityNameFromAlias(alias); - 3051790                            sAttributeName = c.AttributeName.Split('.')[1]; - 3051791                        }1792                        else - 15101793                        { - 15101794                            sEntityName = qe.EntityName; //Attributes from the root entity - 15101795                        } - 18151796                    } + 121781            return Expression.AndAlso(containsAttributeExpr, + 121782                            Expression.AndAlso(Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), + 121783                                lessThanExpression)); + 121784        }17851786        protected static Expression TranslateConditionExpressionEndsWith(TypedConditionExpression tc, Expression getAttr + 181787        { + 181788            var c = tc.CondExpression;17891790            //Append a ´%´at the end of each condition value + 361791            var computedCondition = new ConditionExpression(c.AttributeName, c.Operator, c.Values.Select(x => "%" + x.To + 181792            var typedComputedCondition = new TypedConditionExpression(computedCondition); + 181793            typedComputedCondition.AttributeType = tc.AttributeType;1794 + 181795            return TranslateConditionExpressionLike(typedComputedCondition, getAttributeValueExpr, containsAttributeExpr + 181796        }  17971798#else1799                    //CRM 2011 - 4311800                     if (c.AttributeName.IndexOf(".") >= 0) { - 721801                        var alias = c.AttributeName.Split('.')[0]; - 721802                        sEntityName = qe.GetEntityNameFromAlias(alias); - 721803                        sAttributeName = c.AttributeName.Split('.')[1]; - 721804                    }1805#endif1806 - 22491807                    var earlyBoundType = context.FindReflectedType(sEntityName); - 22491808                     if (earlyBoundType != null) - 22431809                    { - 22431810                        typedExpression.AttributeType = context.FindReflectedAttributeType(earlyBoundType, sEntityName, 1798        protected static Expression GetToStringExpression<T>(Expression e) + 521799        { + 521800            return Expression.Call(e, typeof(T).GetMethod("ToString", new Type[] { })); + 521801        }1802        protected static Expression GetCaseInsensitiveExpression(Expression e) + 26611803        { + 26611804            return Expression.Call(e, + 26611805                                typeof(string).GetMethod("ToLowerInvariant", new Type[] { })); + 26611806        }18071808        protected static Expression TranslateConditionExpressionLike(TypedConditionExpression tc, Expression getAttribut + 1201809        { + 1201810            var c = tc.CondExpression;  18111812                        // Special case when filtering on the name of a Lookup - 22371813                         if (typedExpression.AttributeType == typeof(EntityReference) && sAttributeName.EndsWith("name")) - 61814                        { - 61815                            var realAttributeName = c.AttributeName.Substring(0, c.AttributeName.Length - 4); + 1201812            BinaryExpression expOrValues = Expression.Or(Expression.Constant(false), Expression.Constant(false)); + 1201813            Expression convertedValueToStr = Expression.Convert(GetAppropiateCastExpressionBasedOnType(tc.AttributeType,1814 + 1201815            Expression convertedValueToStrAndToLower = GetCaseInsensitiveExpression(convertedValueToStr);  1816 - 61817                             if (GetEarlyBoundTypeAttribute(earlyBoundType, sAttributeName) == null && GetEarlyBoundTypeA - 61818                            {1819                                // Need to make Lookups work against the real attribute, not the "name" suffixed attribu - 61820                                c.AttributeName = realAttributeName; - 61821                            } - 61822                        } - 22371823                    } - 22431824                } + 1201817            string sLikeOperator = "%"; + 6001818            foreach (object value in c.Values) + 1201819            { + 1201820                var strValue = value.ToString(); + 1201821                string sMethod = "";1822 + 1201823                 if (strValue.EndsWith(sLikeOperator) && strValue.StartsWith(sLikeOperator)) + 361824                    sMethod = "Contains";  1825 - 28431826                ValidateSupportedTypedExpression(typedExpression);18271828                //Build a binary expression - 28421829                 if (op == LogicalOperator.And) - 27761830                { - 27761831                    binaryExpression = Expression.And(binaryExpression, TranslateConditionExpression(qe, context, typedE - 27501832                }1833                else - 661834                    binaryExpression = Expression.Or(binaryExpression, TranslateConditionExpression(qe, context, typedEx - 28161835            }1836 - 21351837            return binaryExpression; - 21351838        }18391840        protected static BinaryExpression TranslateMultipleFilterExpressions(QueryExpression qe, XrmFakedContext context - 2161841        { - 2161842            BinaryExpression binaryExpression = null; - 2161843             if (op == LogicalOperator.And) - 2041844                binaryExpression = Expression.And(Expression.Constant(true), Expression.Constant(true));1845            else - 121846                binaryExpression = Expression.Or(Expression.Constant(false), Expression.Constant(false)); + 841826                 else if (strValue.StartsWith(sLikeOperator)) + 181827                    sMethod = "EndsWith";18281829                else + 661830                    sMethod = "StartsWith";1831 + 1201832                expOrValues = Expression.Or(expOrValues, Expression.Call( + 1201833                    convertedValueToStrAndToLower, + 1201834                    typeof(string).GetMethod(sMethod, new Type[] { typeof(string) }), + 1201835                    Expression.Constant(value.ToString().ToLowerInvariant().Replace("%", "")) //Linq2CRM adds the percen + 1201836                )); + 1201837            }1838 + 1201839            return Expression.AndAlso( + 1201840                            containsAttributeExpr, + 1201841                            expOrValues); + 1201842        }18431844        protected static Expression TranslateConditionExpressionContains(TypedConditionExpression tc, Expression getAttr + 241845        { + 241846            var c = tc.CondExpression;  1847 - 11161848            foreach (var f in filters) - 2341849            { - 2341850                var thisFilterLambda = TranslateFilterExpressionToExpression(qe, context, sEntityName, f, entity, bIsOut18511852                //Build a binary expression - 2341853                 if (op == LogicalOperator.And) - 2161854                { - 2161855                    binaryExpression = Expression.And(binaryExpression, thisFilterLambda); - 2161856                }1857                else - 181858                    binaryExpression = Expression.Or(binaryExpression, thisFilterLambda); - 2341859            }1860 - 2161861            return binaryExpression; - 2161862        }18631864        protected static List<Expression> TranslateLinkedEntityFilterExpressionToExpression(QueryExpression qe, XrmFaked - 15431865        {1866            //In CRM 2011, condition expressions are at the LinkEntity level without an entity name1867            //From CRM 2013, condition expressions were moved to outside the LinkEntity object at the QueryExpression le1868            //with an EntityName alias attribute18691870            //If we reach this point, it means we are translating filters at the Link Entity level (2011),1871            //Therefore we need to prepend the alias attribute because the code to generate attributes for Joins (JoinAt - 15431872            var linkedEntitiesQueryExpressions = new List<Expression>();1848            //Append a ´%´at the end of each condition value + 481849            var computedCondition = new ConditionExpression(c.AttributeName, c.Operator, c.Values.Select(x => "%" + x.To + 241850            var computedTypedCondition = new TypedConditionExpression(computedCondition); + 241851            computedTypedCondition.AttributeType = tc.AttributeType;1852 + 241853            return TranslateConditionExpressionLike(computedTypedCondition, getAttributeValueExpr, containsAttributeExpr1854 + 241855        }18561857        protected static BinaryExpression TranslateMultipleConditionExpressions(QueryExpression qe, XrmFakedContext cont + 22241858        { + 22241859            BinaryExpression binaryExpression = null;  //Default initialisation depending on logical operator + 22241860             if (op == LogicalOperator.And) + 21881861                binaryExpression = Expression.And(Expression.Constant(true), Expression.Constant(true));1862            else + 361863                binaryExpression = Expression.Or(Expression.Constant(false), Expression.Constant(false));1864 + 124971865            foreach (var c in conditions) + 29291866            { + 29291867                var cEntityName = sEntityName;1868                //Create a new typed expression + 29291869                var typedExpression = new TypedConditionExpression(c); + 29291870                typedExpression.IsOuter = bIsOuter;1871 + 29291872                string sAttributeName = c.AttributeName;  1873 - 15431874             if (le.LinkCriteria != null) - 14541875            { - 14541876                var earlyBoundType = context.FindReflectedType(le.LinkToEntityName); - 14541877                 var attributeMetadata = context.AttributeMetadataNames.ContainsKey(le.LinkToEntityName) ? context.Attrib1878 - 53201879                foreach (var ce in le.LinkCriteria.Conditions) - 4791880                { - 4791881                     if (earlyBoundType != null) - 3671882                    { - 3671883                        var attributeInfo = GetEarlyBoundTypeAttribute(earlyBoundType, ce.AttributeName); - 3671884                         if (attributeInfo == null && ce.AttributeName.EndsWith("name")) - 01885                        {1886                            // Special case for referencing the name of a EntityReference - 01887                            var sAttributeName = ce.AttributeName.Substring(0, ce.AttributeName.Length - 4); - 01888                            attributeInfo = GetEarlyBoundTypeAttribute(earlyBoundType, sAttributeName);1889 - 01890                             if (attributeInfo.PropertyType == typeof(EntityReference)) - 01891                            {1892                                // Don't mess up if other attributes follow this naming pattern - 01893                                ce.AttributeName = sAttributeName; - 01894                            } - 01895                        } - 3671896                    } - 1121897                     else if (attributeMetadata != null && !attributeMetadata.ContainsKey(ce.AttributeName) && ce.Attribu - 01898                    {1899                        // Special case for referencing the name of a EntityReference - 01900                        var sAttributeName = ce.AttributeName.Substring(0, ce.AttributeName.Length - 4); - 01901                         if (attributeMetadata.ContainsKey(sAttributeName)) - 01902                        { - 01903                            ce.AttributeName = sAttributeName; - 01904                        } - 01905                    }1906 - 4791907                     var entityAlias = !string.IsNullOrEmpty(le.EntityAlias) ? le.EntityAlias : le.LinkToEntityName; - 4791908                    ce.AttributeName = entityAlias + "." + ce.AttributeName; - 4791909                }1910 - 43821911                foreach (var fe in le.LinkCriteria.Filters) - 101912                { - 501913                    foreach (var ce in fe.Conditions) - 101914                    { - 101915                         var entityAlias = !string.IsNullOrEmpty(le.EntityAlias) ? le.EntityAlias : le.LinkToEntityName; - 101916                        ce.AttributeName = entityAlias + "." + ce.AttributeName; - 101917                    } - 101918                } - 14541919            }1874                //Find the attribute type if using early bound entities + 29291875                 if (context.ProxyTypesAssembly != null) + 22791876                {18771878#if FAKE_XRM_EASY_2013 || FAKE_XRM_EASY_2015 || FAKE_XRM_EASY_2016 || FAKE_XRM_EASY_365 || FAKE_XRM_EASY_9 + 19151879                     if (c.EntityName != null) + 751880                        cEntityName = qe.GetEntityNameFromAlias(c.EntityName);1881                    else + 18401882                    { + 18401883                         if (c.AttributeName.IndexOf(".") >= 0) + 3051884                        { + 3051885                            var alias = c.AttributeName.Split('.')[0]; + 3051886                            cEntityName = qe.GetEntityNameFromAlias(alias); + 3051887                            sAttributeName = c.AttributeName.Split('.')[1]; + 3051888                        } + 18401889                    }18901891#else1892                    //CRM 2011 + 4361893                     if (c.AttributeName.IndexOf(".") >= 0) { + 721894                        var alias = c.AttributeName.Split('.')[0]; + 721895                        cEntityName = qe.GetEntityNameFromAlias(alias); + 721896                        sAttributeName = c.AttributeName.Split('.')[1]; + 721897                    }1898#endif1899 + 22791900                    var earlyBoundType = context.FindReflectedType(cEntityName); + 22791901                     if (earlyBoundType != null) + 22731902                    { + 22731903                        typedExpression.AttributeType = context.FindReflectedAttributeType(earlyBoundType, cEntityName, 19041905                        // Special case when filtering on the name of a Lookup + 22671906                         if (typedExpression.AttributeType == typeof(EntityReference) && sAttributeName.EndsWith("name")) + 61907                        { + 61908                            var realAttributeName = c.AttributeName.Substring(0, c.AttributeName.Length - 4);1909 + 61910                             if (GetEarlyBoundTypeAttribute(earlyBoundType, sAttributeName) == null && GetEarlyBoundTypeA + 61911                            {1912                                // Need to make Lookups work against the real attribute, not the "name" suffixed attribu + 61913                                c.AttributeName = realAttributeName; + 61914                            } + 61915                        } + 22671916                    } + 22731917                }1918 + 29231919                ValidateSupportedTypedExpression(typedExpression);  19201921            //Translate this specific Link Criteria - 15431922            linkedEntitiesQueryExpressions.Add(TranslateFilterExpressionToExpression(qe, context, le.LinkToEntityName, l19231924            //Processed nested linked entities - 48571925            foreach (var nestedLinkedEntity in le.LinkEntities) - 1141926            { - 1141927                var listOfExpressions = TranslateLinkedEntityFilterExpressionToExpression(qe, context, nestedLinkedEntit - 1141928                linkedEntitiesQueryExpressions.AddRange(listOfExpressions); - 1141929            }1930 - 15431931            return linkedEntitiesQueryExpressions; - 15431932        }19331934        protected static Expression TranslateQueryExpressionFiltersToExpression(XrmFakedContext context, QueryExpression - 27791935        { - 27791936            var linkedEntitiesQueryExpressions = new List<Expression>(); - 111951937            foreach (var le in qe.LinkEntities) - 14291938            { - 14291939                var listOfExpressions = TranslateLinkedEntityFilterExpressionToExpression(qe, context, le, entity); - 14291940                linkedEntitiesQueryExpressions.AddRange(listOfExpressions); - 14291941            }1942 - 27791943             if (linkedEntitiesQueryExpressions.Count > 0 && qe.Criteria != null) - 8111944            {1945                //Return the and of the two - 8111946                Expression andExpression = Expression.Constant(true); - 54351947                foreach (var e in linkedEntitiesQueryExpressions) - 15011948                { - 15011949                    andExpression = Expression.And(e, andExpression);1950 - 15011951                } - 8111952                var feExpression = TranslateFilterExpressionToExpression(qe, context, qe.EntityName, qe.Criteria, entity - 8111953                return Expression.And(andExpression, feExpression);1954            } - 19681955             else if (linkedEntitiesQueryExpressions.Count > 0) - 241956            {1957                //Linked entity expressions only - 241958                Expression andExpression = Expression.Constant(true); - 1561959                foreach (var e in linkedEntitiesQueryExpressions) - 421960                { - 421961                    andExpression = Expression.And(e, andExpression);1921                //Build a binary expression + 29221922                 if (op == LogicalOperator.And) + 28561923                { + 28561924                    binaryExpression = Expression.And(binaryExpression, TranslateConditionExpression(qe, context, typedE + 28301925                }1926                else + 661927                    binaryExpression = Expression.Or(binaryExpression, TranslateConditionExpression(qe, context, typedEx + 28961928            }1929 + 21911930            return binaryExpression; + 21911931        }19321933        protected static BinaryExpression TranslateMultipleFilterExpressions(QueryExpression qe, XrmFakedContext context + 2401934        { + 2401935            BinaryExpression binaryExpression = null; + 2401936             if (op == LogicalOperator.And) + 2161937                binaryExpression = Expression.And(Expression.Constant(true), Expression.Constant(true));1938            else + 241939                binaryExpression = Expression.Or(Expression.Constant(false), Expression.Constant(false));1940 + 12601941            foreach (var f in filters) + 2701942            { + 2701943                var thisFilterLambda = TranslateFilterExpressionToExpression(qe, context, sEntityName, f, entity, bIsOut19441945                //Build a binary expression + 2701946                 if (op == LogicalOperator.And) + 2281947                { + 2281948                    binaryExpression = Expression.And(binaryExpression, thisFilterLambda); + 2281949                }1950                else + 421951                    binaryExpression = Expression.Or(binaryExpression, thisFilterLambda); + 2701952            }1953 + 2401954            return binaryExpression; + 2401955        }19561957        protected static List<Expression> TranslateLinkedEntityFilterExpressionToExpression(QueryExpression qe, XrmFaked + 15811958        {1959            //In CRM 2011, condition expressions are at the LinkEntity level without an entity name1960            //From CRM 2013, condition expressions were moved to outside the LinkEntity object at the QueryExpression le1961            //with an EntityName alias attribute  1962 - 421963                } - 241964                return andExpression;1965            }1966            else - 19441967            {1968                //Criteria only - 19441969                return TranslateFilterExpressionToExpression(qe, context, qe.EntityName, qe.Criteria, entity, false);1970            } - 27461971        }1972        protected static Expression TranslateFilterExpressionToExpression(QueryExpression qe, XrmFakedContext context, s - 45321973        { - 47951974             if (fe == null) return Expression.Constant(true);1975 - 42691976            BinaryExpression conditionsLambda = null; - 42691977            BinaryExpression filtersLambda = null; - 42691978             if (fe.Conditions != null && fe.Conditions.Count > 0) - 21681979            { - 21681980                conditionsLambda = TranslateMultipleConditionExpressions(qe, context, sEntityName, fe.Conditions.ToList( - 21351981            }1963            //If we reach this point, it means we are translating filters at the Link Entity level (2011),1964            //Therefore we need to prepend the alias attribute because the code to generate attributes for Joins (JoinAt + 15811965            var linkedEntitiesQueryExpressions = new List<Expression>();1966 + 15811967             if (le.LinkCriteria != null) + 14821968            { + 14821969                var earlyBoundType = context.FindReflectedType(le.LinkToEntityName); + 14821970                 var attributeMetadata = context.AttributeMetadataNames.ContainsKey(le.LinkToEntityName) ? context.Attrib1971 + 54041972                foreach (var ce in le.LinkCriteria.Conditions) + 4791973                { + 4791974                     if (earlyBoundType != null) + 3671975                    { + 3671976                        var attributeInfo = GetEarlyBoundTypeAttribute(earlyBoundType, ce.AttributeName); + 3671977                         if (attributeInfo == null && ce.AttributeName.EndsWith("name")) + 01978                        {1979                            // Special case for referencing the name of a EntityReference + 01980                            var sAttributeName = ce.AttributeName.Substring(0, ce.AttributeName.Length - 4); + 01981                            attributeInfo = GetEarlyBoundTypeAttribute(earlyBoundType, sAttributeName);  19821983            //Process nested filters recursively - 42361984             if (fe.Filters != null && fe.Filters.Count > 0) - 2161985            { - 2161986                filtersLambda = TranslateMultipleFilterExpressions(qe, context, sEntityName, fe.Filters.ToList(), fe.Fil - 2161987            }1988 - 42361989             if (conditionsLambda != null && filtersLambda != null) - 421990            {1991                //Satisfy both - 421992                 if (fe.FilterOperator == LogicalOperator.And) - 361993                { - 361994                    return Expression.And(conditionsLambda, filtersLambda);1995                }1996                else - 61997                { - 61998                    return Expression.Or(conditionsLambda, filtersLambda);1999                }2000            } - 41942001             else if (conditionsLambda != null) - 20932002                return conditionsLambda; - 21012003             else if (filtersLambda != null) - 1742004                return filtersLambda;2005 - 19272006            return Expression.Constant(true); //Satisfy filter if there are no conditions nor filters - 44992007        }2008        protected static Expression TranslateConditionExpressionNext(TypedConditionExpression tc, Expression getAttribut - 62009        { - 62010            var c = tc.CondExpression;2011 - 62012            var nextDateTime = default(DateTime); - 62013            var currentDateTime = DateTime.UtcNow; - 62014             var numberOfWeeks = c.Values.Any() ? (int)c.Values[0] : 1;2015 - 62016             switch (c.Operator)2017            {2018                case ConditionOperator.NextXWeeks: - 62019                    nextDateTime = currentDateTime.AddDays(7 * numberOfWeeks); - 62020                    c.Values[0] = (currentDateTime); - 62021                    c.Values.Add(nextDateTime); - 62022                    c.Values.Add(numberOfWeeks); - 62023                    break;2024                case ConditionOperator.Next7Days: - 02025                    nextDateTime = currentDateTime.AddDays(7 * numberOfWeeks); - 02026                    c.Values.Add(currentDateTime); - 02027                    c.Values.Add(nextDateTime); - 02028                    break;2029            }2030 - 62031            return TranslateConditionExpressionBetween(tc, getAttributeValueExpr, containsAttributeExpr); - 62032        }20332034#if FAKE_XRM_EASY_92035        protected static Expression TranslateConditionExpressionContainValues(TypedConditionExpression tc, Expression ge - 142036        { - 142037            var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, - 142038            var rightHandSideExpression = Expression.Constant(ConvertToHashSetOfInt(tc.CondExpression.Values, isOptionSe2039 - 122040            return Expression.AndAlso( - 122041                       containsAttributeExpr, - 122042                       Expression.AndAlso( - 122043                           Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), - 122044                           Expression.Equal( - 122045                               Expression.Call(leftHandSideExpression, typeof(HashSet<int>).GetMethod("Overlaps"), right - 122046                               Expression.Constant(true)))); - 122047        }2048#endif2049    }2050} + 01983                             if (attributeInfo.PropertyType == typeof(EntityReference)) + 01984                            {1985                                // Don't mess up if other attributes follow this naming pattern + 01986                                ce.AttributeName = sAttributeName; + 01987                            } + 01988                        } + 3671989                    } + 1121990                     else if (attributeMetadata != null && !attributeMetadata.ContainsKey(ce.AttributeName) && ce.Attribu + 01991                    {1992                        // Special case for referencing the name of a EntityReference + 01993                        var sAttributeName = ce.AttributeName.Substring(0, ce.AttributeName.Length - 4); + 01994                         if (attributeMetadata.ContainsKey(sAttributeName)) + 01995                        { + 01996                            ce.AttributeName = sAttributeName; + 01997                        } + 01998                    }1999 + 4792000                     var entityAlias = !string.IsNullOrEmpty(le.EntityAlias) ? le.EntityAlias : le.LinkToEntityName; + 4792001                    ce.AttributeName = entityAlias + "." + ce.AttributeName; + 4792002                }2003 + 44902004                foreach (var fe in le.LinkCriteria.Filters) + 222005                { + 862006                    foreach (var ce in fe.Conditions) + 102007                    { + 102008                         var entityAlias = !string.IsNullOrEmpty(le.EntityAlias) ? le.EntityAlias : le.LinkToEntityName; + 102009                        ce.AttributeName = entityAlias + "." + ce.AttributeName; + 102010                    } + 222011                } + 14822012            }20132014            //Translate this specific Link Criteria + 15812015            linkedEntitiesQueryExpressions.Add(TranslateFilterExpressionToExpression(qe, context, le.LinkToEntityName, l20162017            //Processed nested linked entities + 49712018            foreach (var nestedLinkedEntity in le.LinkEntities) + 1142019            { + 1142020                var listOfExpressions = TranslateLinkedEntityFilterExpressionToExpression(qe, context, nestedLinkedEntit + 1142021                linkedEntitiesQueryExpressions.AddRange(listOfExpressions); + 1142022            }2023 + 15812024            return linkedEntitiesQueryExpressions; + 15812025        }20262027        protected static Expression TranslateQueryExpressionFiltersToExpression(XrmFakedContext context, QueryExpression + 28172028        { + 28172029            var linkedEntitiesQueryExpressions = new List<Expression>(); + 113852030            foreach (var le in qe.LinkEntities) + 14672031            { + 14672032                var listOfExpressions = TranslateLinkedEntityFilterExpressionToExpression(qe, context, le, entity); + 14672033                linkedEntitiesQueryExpressions.AddRange(listOfExpressions); + 14672034            }2035 + 28172036             if (linkedEntitiesQueryExpressions.Count > 0 && qe.Criteria != null) + 8492037            {2038                //Return the and of the two + 8492039                Expression andExpression = Expression.Constant(true); + 56252040                foreach (var e in linkedEntitiesQueryExpressions) + 15392041                { + 15392042                    andExpression = Expression.And(e, andExpression);2043 + 15392044                } + 8492045                var feExpression = TranslateFilterExpressionToExpression(qe, context, qe.EntityName, qe.Criteria, entity + 8492046                return Expression.And(andExpression, feExpression);2047            } + 19682048             else if (linkedEntitiesQueryExpressions.Count > 0) + 242049            {2050                //Linked entity expressions only + 242051                Expression andExpression = Expression.Constant(true); + 1562052                foreach (var e in linkedEntitiesQueryExpressions) + 422053                { + 422054                    andExpression = Expression.And(e, andExpression);2055 + 422056                } + 242057                return andExpression;2058            }2059            else + 19442060            {2061                //Criteria only + 19442062                return TranslateFilterExpressionToExpression(qe, context, qe.EntityName, qe.Criteria, entity, false);2063            } + 27842064        }2065        protected static Expression TranslateFilterExpressionToExpression(QueryExpression qe, XrmFakedContext context, s + 46442066        { + 49172067             if (fe == null) return Expression.Constant(true);2068 + 43712069            BinaryExpression conditionsLambda = null; + 43712070            BinaryExpression filtersLambda = null; + 43712071             if (fe.Conditions != null && fe.Conditions.Count > 0) + 22242072            { + 22242073                conditionsLambda = TranslateMultipleConditionExpressions(qe, context, sEntityName, fe.Conditions.ToList( + 21912074            }20752076            //Process nested filters recursively + 43382077             if (fe.Filters != null && fe.Filters.Count > 0) + 2402078            { + 2402079                filtersLambda = TranslateMultipleFilterExpressions(qe, context, sEntityName, fe.Filters.ToList(), fe.Fil + 2402080            }2081 + 43382082             if (conditionsLambda != null && filtersLambda != null) + 422083            {2084                //Satisfy both + 422085                 if (fe.FilterOperator == LogicalOperator.And) + 362086                { + 362087                    return Expression.And(conditionsLambda, filtersLambda);2088                }2089                else + 62090                { + 62091                    return Expression.Or(conditionsLambda, filtersLambda);2092                }2093            } + 42962094             else if (conditionsLambda != null) + 21492095                return conditionsLambda; + 21472096             else if (filtersLambda != null) + 1982097                return filtersLambda;2098 + 19492099            return Expression.Constant(true); //Satisfy filter if there are no conditions nor filters + 46112100        }2101        protected static Expression TranslateConditionExpressionNext(TypedConditionExpression tc, Expression getAttribut + 62102        { + 62103            var c = tc.CondExpression;2104 + 62105            var nextDateTime = default(DateTime); + 62106            var currentDateTime = DateTime.UtcNow; + 62107             var numberOfWeeks = c.Values.Any() ? (int)c.Values[0] : 1;2108 + 62109             switch (c.Operator)2110            {2111                case ConditionOperator.NextXWeeks: + 62112                    nextDateTime = currentDateTime.AddDays(7 * numberOfWeeks); + 62113                    c.Values[0] = (currentDateTime); + 62114                    c.Values.Add(nextDateTime); + 62115                    c.Values.Add(numberOfWeeks); + 62116                    break;2117                case ConditionOperator.Next7Days: + 02118                    nextDateTime = currentDateTime.AddDays(7 * numberOfWeeks); + 02119                    c.Values.Add(currentDateTime); + 02120                    c.Values.Add(nextDateTime); + 02121                    break;2122            }2123 + 62124            return TranslateConditionExpressionBetween(tc, getAttributeValueExpr, containsAttributeExpr); + 62125        }21262127#if FAKE_XRM_EASY_92128        protected static Expression TranslateConditionExpressionContainValues(TypedConditionExpression tc, Expression ge + 142129        { + 142130            var leftHandSideExpression = GetAppropiateCastExpressionBasedOnType(tc.AttributeType, getAttributeValueExpr, + 142131            var rightHandSideExpression = Expression.Constant(ConvertToHashSetOfInt(tc.CondExpression.Values, isOptionSe2132 + 122133            return Expression.AndAlso( + 122134                       containsAttributeExpr, + 122135                       Expression.AndAlso( + 122136                           Expression.NotEqual(getAttributeValueExpr, Expression.Constant(null)), + 122137                           Expression.Equal( + 122138                               Expression.Call(leftHandSideExpression, typeof(HashSet<int>).GetMethod("Overlaps"), right + 122139                               Expression.Constant(true)))); + 122140        }2141#endif2142    }2143} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_XrmFakedPluginExecutionContext.htm b/test/reports/FakeXrmEasy_XrmFakedPluginExecutionContext.htm index 2e83fee0..3cf99a54 100644 --- a/test/reports/FakeXrmEasy_XrmFakedPluginExecutionContext.htm +++ b/test/reports/FakeXrmEasy_XrmFakedPluginExecutionContext.htm @@ -149,6 +149,6 @@

D:\Git  113} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_XrmFakedRelationship.htm b/test/reports/FakeXrmEasy_XrmFakedRelationship.htm index 3870fe78..4681f524 100644 --- a/test/reports/FakeXrmEasy_XrmFakedRelationship.htm +++ b/test/reports/FakeXrmEasy_XrmFakedRelationship.htm @@ -15,11 +15,12 @@

Summary

Class:FakeXrmEasy.XrmFakedRelationship Assembly:FakeXrmEasy File(s):D:\Git\fake-xrm-easy\FakeXrmEasy.Shared\XrmFakedRelationship.cs -Covered lines:27 +Covered lines:43 Uncovered lines:0 -Coverable lines:27 -Total lines:64 +Coverable lines:43 +Total lines:96 Line coverage:100% +Branch coverage:100%

Metrics

@@ -40,68 +41,100 @@

D:\Git\fake-xrm-  2{  3    public class XrmFakedRelationship  4    {5        /// <summary>6        /// Schema name of the many to many intersect entity7        /// </summary> - 15668        public string IntersectEntity { get; set; }910        /// <summary>11        /// Entity name and attribute of the first entity participating in the relationship12        /// </summary> - 109213        public string Entity1Attribute { get; set; }14 - 215415        public string Entity1LogicalName { get; set; }16 - 151217        public string Entity2LogicalName { get; set; }1819        /// <summary>20        /// Entity name and attribute of the second entity participating in the relationship21        /// </summary> - 107422        public string Entity2Attribute { get; set; }23 - 15624        public XrmFakedRelationship() - 15625        { - 15626            RelationshipType = enmFakeRelationshipType.ManyToMany; - 15627        }2829        public enum enmFakeRelationshipType30        {31            ManyToMany = 0,32            OneToMany = 133        }5 + 2106        private string entity1Attribute = string.Empty; + 2107        private string entity2Attribute = string.Empty;89        /// <summary>10        /// Schema name of the many to many intersect entity11        /// </summary> + 159012        public string IntersectEntity { get; set; }1314        /// <summary>15        /// Entity name and attribute of the first entity participating in the relationship16        /// </summary>17        public string Entity1Attribute18        {19            get + 91220            { + 91221                 if (entity1Attribute == entity2Attribute && Entity1LogicalName == Entity2LogicalName) + 622                { + 623                    return entity1Attribute + "one";24                }25                else + 90626                { + 90627                    return entity1Attribute;28                } + 91229            } + 61230            set { entity1Attribute = value; }31        }32 + 221433        public string Entity1LogicalName { get; set; }  34 - 85835        public enmFakeRelationshipType RelationshipType { get; set; } + 156035        public string Entity2LogicalName { get; set; }  36  37        /// <summary>38        /// Initializes a N:N relationship type38        /// Entity name and attribute of the second entity participating in the relationship  39        /// </summary>40        /// <param name="entityName"></param>41        /// <param name="entity1Attribute"></param>42        /// <param name="entity2Attribute"></param>43        /// <param name="entity1LogicalName"></param>44        /// <param name="entity2LogicalName"></param> - 1245        public XrmFakedRelationship(string entityName, string entity1Attribute, string entity2Attribute, string entity1L - 1246        { - 1247            IntersectEntity = entityName; - 1248            Entity1Attribute = entity1Attribute; - 1249            Entity2Attribute = entity2Attribute; - 1250            Entity1LogicalName = entity1LogicalName; - 1251            Entity2LogicalName = entity2LogicalName; - 1252            RelationshipType = enmFakeRelationshipType.ManyToMany; - 1253        }54 - 3055        public XrmFakedRelationship(string entity1Attribute, string entity2Attribute, string entity1LogicalName, string  - 3056        { - 3057            Entity1Attribute = entity1Attribute; - 3058            Entity2Attribute = entity2Attribute; - 3059            Entity1LogicalName = entity1LogicalName; - 3060            Entity2LogicalName = entity2LogicalName; - 3061            RelationshipType = enmFakeRelationshipType.OneToMany; - 3062        }63    }64}40        public string Entity2Attribute41        {42            get + 89443            { + 89444                 if (entity1Attribute == entity2Attribute && Entity1LogicalName == Entity2LogicalName) + 645                { + 646                    return entity2Attribute + "two";47                }48                else + 88849                { + 88850                    return entity2Attribute;51                } + 89452            } + 61253            set { entity2Attribute = value; }54        }55 + 16856        public XrmFakedRelationship() + 16857        { + 16858            RelationshipType = enmFakeRelationshipType.ManyToMany; + 16859        }6061        public enum enmFakeRelationshipType62        {63            ManyToMany = 0,64            OneToMany = 165        }66 + 89467        public enmFakeRelationshipType RelationshipType { get; set; }6869        /// <summary>70        /// Initializes a N:N relationship type71        /// </summary>72        /// <param name="entityName"></param>73        /// <param name="entity1Attribute"></param>74        /// <param name="entity2Attribute"></param>75        /// <param name="entity1LogicalName"></param>76        /// <param name="entity2LogicalName"></param> + 1277        public XrmFakedRelationship(string entityName, string entity1Attribute, string entity2Attribute, string entity1L + 1278        { + 1279            IntersectEntity = entityName; + 1280            Entity1Attribute = entity1Attribute; + 1281            Entity2Attribute = entity2Attribute; + 1282            Entity1LogicalName = entity1LogicalName; + 1283            Entity2LogicalName = entity2LogicalName; + 1284            RelationshipType = enmFakeRelationshipType.ManyToMany; + 1285        }86 + 3087        public XrmFakedRelationship(string entity1Attribute, string entity2Attribute, string entity1LogicalName, string  + 3088        { + 3089            Entity1Attribute = entity1Attribute; + 3090            Entity2Attribute = entity2Attribute; + 3091            Entity1LogicalName = entity1LogicalName; + 3092            Entity2LogicalName = entity2LogicalName; + 3093            RelationshipType = enmFakeRelationshipType.OneToMany; + 3094        }95    }96} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_XrmFakedTracingService.htm b/test/reports/FakeXrmEasy_XrmFakedTracingService.htm index a36e33af..0c8c72c8 100644 --- a/test/reports/FakeXrmEasy_XrmFakedTracingService.htm +++ b/test/reports/FakeXrmEasy_XrmFakedTracingService.htm @@ -74,6 +74,6 @@

D:\Git\fake-xr  35} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_XrmFakedWorkflowContext.htm b/test/reports/FakeXrmEasy_XrmFakedWorkflowContext.htm index e6a5a704..4564311d 100644 --- a/test/reports/FakeXrmEasy_XrmFakedWorkflowContext.htm +++ b/test/reports/FakeXrmEasy_XrmFakedWorkflowContext.htm @@ -98,6 +98,6 @@

D:\Git\fake-x  69} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_XrmOrderByAttributeComparer.htm b/test/reports/FakeXrmEasy_XrmOrderByAttributeComparer.htm index e692daad..36ffe92b 100644 --- a/test/reports/FakeXrmEasy_XrmOrderByAttributeComparer.htm +++ b/test/reports/FakeXrmEasy_XrmOrderByAttributeComparer.htm @@ -132,6 +132,6 @@

D:\Git\fa  95} - + \ No newline at end of file diff --git a/test/reports/FakeXrmEasy_XrmRealContext.htm b/test/reports/FakeXrmEasy_XrmRealContext.htm index c1357bd6..b353259c 100644 --- a/test/reports/FakeXrmEasy_XrmRealContext.htm +++ b/test/reports/FakeXrmEasy_XrmRealContext.htm @@ -175,6 +175,6 @@

D:\Git\fake-xrm-easy\F  132} - + \ No newline at end of file diff --git a/test/reports/badge_branchcoverage.svg b/test/reports/badge_branchcoverage.svg index 527c8842..6e59f641 100644 --- a/test/reports/badge_branchcoverage.svg +++ b/test/reports/badge_branchcoverage.svg @@ -78,7 +78,7 @@ Coverage Coverage - 74.1%74.1% + 74.2%74.2% diff --git a/test/reports/badge_combined.svg b/test/reports/badge_combined.svg index 0e6bc745..23f86f4b 100644 --- a/test/reports/badge_combined.svg +++ b/test/reports/badge_combined.svg @@ -77,8 +77,8 @@ Coverage Coverage - 89.5%89.5% - 74.1%74.1% + 89.6%89.6% + 74.2%74.2% diff --git a/test/reports/badge_linecoverage.svg b/test/reports/badge_linecoverage.svg index 7f18f7e2..2d070393 100644 --- a/test/reports/badge_linecoverage.svg +++ b/test/reports/badge_linecoverage.svg @@ -77,7 +77,7 @@ Coverage Coverage - 89.5%89.5% + 89.6%89.6% diff --git a/test/reports/combined.js b/test/reports/combined.js index 1e70e16e..377d2ae9 100644 --- a/test/reports/combined.js +++ b/test/reports/combined.js @@ -318,9 +318,9 @@ var assemblies = [ { "name" : "FakeXrmEasy.Extensions.ArrayTraverse", "reportPath" : "FakeXrmEasy_ArrayTraverse.htm", "coveredLines" : 20, "uncoveredLines" : 3, "coverableLines" : 23, "totalLines" : 172, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 7, "totalBranches" : 8, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.Extensions.DateTimeExtensions", "reportPath" : "FakeXrmEasy_DateTimeExtensions.htm", "coveredLines" : 9, "uncoveredLines" : 10, "coverableLines" : 19, "totalLines" : 43, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 0, "totalBranches" : 2, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.Extensions.EntityExtensions", "reportPath" : "FakeXrmEasy_EntityExtensions.htm", "coveredLines" : 283, "uncoveredLines" : 83, "coverableLines" : 366, "totalLines" : 549, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 175, "totalBranches" : 215, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, - { "name" : "FakeXrmEasy.Extensions.EntityMetadataExtensions", "reportPath" : "FakeXrmEasy_EntityMetadataExtensions.htm", "coveredLines" : 23, "uncoveredLines" : 0, "coverableLines" : 23, "totalLines" : 47, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 2, "totalBranches" : 2, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, + { "name" : "FakeXrmEasy.Extensions.EntityMetadataExtensions", "reportPath" : "FakeXrmEasy_EntityMetadataExtensions.htm", "coveredLines" : 29, "uncoveredLines" : 0, "coverableLines" : 29, "totalLines" : 57, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 2, "totalBranches" : 2, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.Extensions.EntityReferenceExtensions", "reportPath" : "FakeXrmEasy_EntityReferenceExtensions.htm", "coveredLines" : 4, "uncoveredLines" : 3, "coverableLines" : 7, "totalLines" : 24, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 1, "totalBranches" : 2, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, - { "name" : "FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml", "reportPath" : "FakeXrmEasy_XmlExtensionsForFetchXml.htm", "coveredLines" : 470, "uncoveredLines" : 31, "coverableLines" : 501, "totalLines" : 801, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 304, "totalBranches" : 481, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, + { "name" : "FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml", "reportPath" : "FakeXrmEasy_XmlExtensionsForFetchXml.htm", "coveredLines" : 472, "uncoveredLines" : 29, "coverableLines" : 501, "totalLines" : 801, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 306, "totalBranches" : 481, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.Extensions.ObjectExtensions", "reportPath" : "FakeXrmEasy_ObjectExtensions.htm", "coveredLines" : 65, "uncoveredLines" : 13, "coverableLines" : 78, "totalLines" : 172, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 22, "totalBranches" : 30, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.Extensions.QueryExpressionExtensions", "reportPath" : "FakeXrmEasy_QueryExpressionExtensions.htm", "coveredLines" : 13, "uncoveredLines" : 1, "coverableLines" : 14, "totalLines" : 36, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 3, "totalBranches" : 4, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.Extensions.ReferenceEqualityComparer", "reportPath" : "FakeXrmEasy_ReferenceEqualityComparer.htm", "coveredLines" : 7, "uncoveredLines" : 0, "coverableLines" : 7, "totalLines" : 172, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 1, "totalBranches" : 2, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, @@ -382,9 +382,9 @@ var assemblies = [ { "name" : "FakeXrmEasy.Services.DefaultEntityInitializerService", "reportPath" : "FakeXrmEasy_DefaultEntityInitializerService.htm", "coveredLines" : 36, "uncoveredLines" : 3, "coverableLines" : 39, "totalLines" : 74, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 10, "totalBranches" : 10, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.Services.InvoiceDetailInitializerService", "reportPath" : "FakeXrmEasy_InvoiceDetailInitializerService.htm", "coveredLines" : 75, "uncoveredLines" : 3, "coverableLines" : 78, "totalLines" : 123, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 32, "totalBranches" : 32, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.Services.InvoiceInitializerService", "reportPath" : "FakeXrmEasy_InvoiceInitializerService.htm", "coveredLines" : 7, "uncoveredLines" : 3, "coverableLines" : 10, "totalLines" : 28, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 1, "totalBranches" : 2, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, - { "name" : "FakeXrmEasy.XrmFakedContext", "reportPath" : "FakeXrmEasy_XrmFakedContext.htm", "coveredLines" : 2461, "uncoveredLines" : 313, "coverableLines" : 2774, "totalLines" : 4557, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 749, "totalBranches" : 1033, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, + { "name" : "FakeXrmEasy.XrmFakedContext", "reportPath" : "FakeXrmEasy_XrmFakedContext.htm", "coveredLines" : 2530, "uncoveredLines" : 318, "coverableLines" : 2848, "totalLines" : 4651, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 786, "totalBranches" : 1083, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.XrmFakedPluginExecutionContext", "reportPath" : "FakeXrmEasy_XrmFakedPluginExecutionContext.htm", "coveredLines" : 34, "uncoveredLines" : 3, "coverableLines" : 37, "totalLines" : 113, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 0, "totalBranches" : 0, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, - { "name" : "FakeXrmEasy.XrmFakedRelationship", "reportPath" : "FakeXrmEasy_XrmFakedRelationship.htm", "coveredLines" : 27, "uncoveredLines" : 0, "coverableLines" : 27, "totalLines" : 64, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 0, "totalBranches" : 0, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, + { "name" : "FakeXrmEasy.XrmFakedRelationship", "reportPath" : "FakeXrmEasy_XrmFakedRelationship.htm", "coveredLines" : 43, "uncoveredLines" : 0, "coverableLines" : 43, "totalLines" : 96, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 4, "totalBranches" : 4, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.XrmFakedTracingService", "reportPath" : "FakeXrmEasy_XrmFakedTracingService.htm", "coveredLines" : 18, "uncoveredLines" : 0, "coverableLines" : 18, "totalLines" : 35, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 2, "totalBranches" : 2, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.XrmFakedWorkflowContext", "reportPath" : "FakeXrmEasy_XrmFakedWorkflowContext.htm", "coveredLines" : 11, "uncoveredLines" : 18, "coverableLines" : 29, "totalLines" : 69, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 0, "totalBranches" : 0, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, { "name" : "FakeXrmEasy.XrmOrderByAttributeComparer", "reportPath" : "FakeXrmEasy_XrmOrderByAttributeComparer.htm", "coveredLines" : 58, "uncoveredLines" : 4, "coverableLines" : 62, "totalLines" : 95, "coverageType" : "LineCoverage", "methodCoverage" : "-", "coveredBranches" : 63, "totalBranches" : 72, "lineCoverageHistory" : [], "branchCoverageHistory" : [] }, diff --git a/test/reports/index.htm b/test/reports/index.htm index bfde474f..c18e6070 100644 --- a/test/reports/index.htm +++ b/test/reports/index.htm @@ -12,17 +12,17 @@

Summary

-Generated on:04/07/2019 - 2:55:29 +Generated on:29/07/2019 - 23:30:56 Parser:MultiReportParser (6x OpenCoverParser) Assemblies:1 Classes:75 Files:80 -Covered lines:5749 -Uncovered lines:668 -Coverable lines:6417 -Total lines:11431 -Line coverage:89.5% -Branch coverage:74.1% +Covered lines:5842 +Uncovered lines:671 +Coverable lines:6513 +Total lines:11567 +Line coverage:89.6% +Branch coverage:74.2%

Assemblies

@@ -44,14 +44,14 @@

Assemblies

NameCoveredUncoveredCoverableTotalLine coverageBranch coverage -FakeXrmEasy574966864171143189.5%
  
74.1%
  
+FakeXrmEasy584267165131156789.6%
  
74.2%
  
FakeXrmEasy.Extensions.ArrayExtensions606172100%
 
100%
 
FakeXrmEasy.Extensions.ArrayTraverse2032317286.9%
  
87.5%
  
FakeXrmEasy.Extensions.DateTimeExtensions910194347.3%
  
0%
 
FakeXrmEasy.Extensions.EntityExtensions2838336654977.3%
  
81.3%
  
-FakeXrmEasy.Extensions.EntityMetadataExtensions2302347100%
 
100%
 
+FakeXrmEasy.Extensions.EntityMetadataExtensions2902957100%
 
100%
 
FakeXrmEasy.Extensions.EntityReferenceExtensions4372457.1%
  
50%
  
-FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml4703150180193.8%
  
63.2%
  
+FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml4722950180194.2%
  
63.6%
  
FakeXrmEasy.Extensions.ObjectExtensions65137817283.3%
  
73.3%
  
FakeXrmEasy.Extensions.QueryExpressionExtensions131143692.8%
  
75%
  
FakeXrmEasy.Extensions.ReferenceEqualityComparer707172100%
 
50%
  
@@ -113,15 +113,15 @@

Assemblies

FakeXrmEasy.Services.DefaultEntityInitializerService363397492.3%
  
100%
 
FakeXrmEasy.Services.InvoiceDetailInitializerService7537812396.1%
  
100%
 
FakeXrmEasy.Services.InvoiceInitializerService73102870%
  
50%
  
-FakeXrmEasy.XrmFakedContext24613132774455788.7%
  
72.5%
  
+FakeXrmEasy.XrmFakedContext25303182848465188.8%
  
72.5%
  
FakeXrmEasy.XrmFakedPluginExecutionContext3433711391.8%
  
 
-FakeXrmEasy.XrmFakedRelationship2702764100%
 
 
+FakeXrmEasy.XrmFakedRelationship4304396100%
 
100%
 
FakeXrmEasy.XrmFakedTracingService1801835100%
 
100%
 
FakeXrmEasy.XrmFakedWorkflowContext1118296937.9%
  
 
FakeXrmEasy.XrmOrderByAttributeComparer584629593.5%
  
87.5%
  
FakeXrmEasy.XrmRealContext5926113296.7%
  
70%
  
- + \ No newline at end of file