From e6b3c72d4f8a28713c4d268b95480e19a17b3cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Kr=C3=B6nert?= Date: Wed, 2 May 2018 22:17:12 +0200 Subject: [PATCH] Added functions for adding child filters and conditions post fluent query creation. Added NoLock explanation to ReadMe --- README.md | 11 +- build.fsx | 4 +- coverage.xml | 765 ++++---- ....FluentQuery_FluentConditionExpression.htm | 1567 ++++++++-------- ...Oss.FluentQuery_FluentFilterExpression.htm | 1557 ++++++++-------- .../Xrm.Oss.FluentQuery_FluentLinkEntity.htm | 1569 ++++++++-------- ....Oss.FluentQuery_FluentOrderExpression.htm | 1561 ++++++++-------- .../Xrm.Oss.FluentQuery_FluentPagingInfo.htm | 1559 ++++++++-------- reports/Xrm.Oss.FluentQuery_FluentQuery_1.htm | 1583 +++++++++-------- ...tQuery_IOrganizationServiceFluentQuery.htm | 1551 ++++++++-------- reports/combined.js | 14 +- reports/index.htm | 26 +- src/lib/Xrm.Oss.FluentQuery/FluentQuery.cs | 49 + .../FluentQueryTests.cs | 124 ++ 14 files changed, 6257 insertions(+), 5683 deletions(-) diff --git a/README.md b/README.md index 170e5b2..7a4fee1 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,13 @@ This library can be used in CRM Plugins / Workflow Activities and in code of ext It does not include references / dependencies to any CRM SDK, so you can just install it and choose the CRM SDK that you need yourself. All CRM versions from 2011 to 365 are supported, just include the one you need to your project. +# Remarks +This library sets the NoLock parameter on your QueryExpressions to true by default (plain QueryExpressions don't). +This is a recommended best practice, as otherwise the records would be locked in the database before retrieval, which might result in decreased performance. +There's also a limit of how much concurrent locked queries can run concurrently. Find out more about NoLock [here](https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.query.queryexpression.nolock.aspx). + +If you choose to lock the data for retrieval, set `service.With.DataBaseLock()`. + # Purpose QueryExpressions add nice IntelliSense, however they tend to be quite verbose, which leads to poor readability. This fluent interface aims to make queries as short and readable as possible while preserving IntelliSense. @@ -18,7 +25,7 @@ This fluent interface aims to make queries as short and readable as possible whi This could look something like this (When not developing early bound, you can simply leave out the generic parameter): ```C# var records = service.Query() - .IncludeColumns("name") + .IncludeColumns("name", "address1_line1") .Where(e => e .Attribute(a => a .Named("name") @@ -41,7 +48,7 @@ The equivalent QueryExpression for above fluent query would be: var query = new QueryExpression { EntityName = "account", - ColumnSet = new ColumnSet("name"), + ColumnSet = new ColumnSet("name", "address1_line1"), NoLock = true, Criteria = new FilterExpression { diff --git a/build.fsx b/build.fsx index d991699..c404862 100644 --- a/build.fsx +++ b/build.fsx @@ -30,8 +30,8 @@ let packagesDir = @".\packages\" // version info let mutable majorversion = "1" -let mutable minorversion = "0" -let mutable build = "1" +let mutable minorversion = "1" +let mutable build = "0" let mutable nugetVersion = "" let mutable asmVersion = "" let mutable asmInfoVersion = "" diff --git a/coverage.xml b/coverage.xml index b84b92b..19c1863 100644 --- a/coverage.xml +++ b/coverage.xml @@ -1,6 +1,6 @@ - + C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll @@ -152,9 +152,9 @@ System.Web - + C:\Users\Florian\Entwicklung\Xrm-Fluent-Query\test\Xrm.Oss.FluentQuery.Tests.dll - 2018-05-01T22:24:25.5868077Z + 2018-05-02T20:15:10.6787899Z Xrm.Oss.FluentQuery.Tests @@ -188,10 +188,10 @@ System.Activities - - + + C:\Users\Florian\Entwicklung\Xrm-Fluent-Query\test\Xrm.Oss.FluentQuery.dll - 2018-05-01T22:24:25.2192794Z + 2018-05-02T20:03:17.4032668Z Xrm.Oss.FluentQuery @@ -238,240 +238,285 @@ Xrm.Oss.FluentQuery.IFluentQuery`1<Microsoft.Xrm.Sdk.Entity> Xrm.Oss.FluentQuery.IOrganizationServiceFluentQuery::Query(Microsoft.Xrm.Sdk.IOrganizationService,System.String) - - - + + + - + - + Xrm.Oss.FluentQuery.FluentQuery`1 - 100663315 + 100663319 Xrm.Oss.FluentQuery.IFluentQuerySetting`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::get_With() - - - + + + - + - 100663326 + 100663332 Microsoft.Xrm.Sdk.Query.QueryExpression Xrm.Oss.FluentQuery.FluentQuery`1::get_Expression() - - - + + + - + - 100663313 + 100663316 System.Void Xrm.Oss.FluentQuery.FluentQuery`1::.ctor(System.String,Microsoft.Xrm.Sdk.IOrganizationService) - - - - - + + + + + - + - - 100663314 + + 100663317 Xrm.Oss.FluentQuery.IFluentQuery`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::IncludeColumns(System.String[]) - - - - + + + + + - + - 100663316 + 100663318 + Xrm.Oss.FluentQuery.IFluentQuery`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::IncludeAllColumns() + + + + + + + + + + + + + 100663320 Xrm.Oss.FluentQuery.IFluentQuery`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::RecordCount(System.Nullable`1<System.Int32>) - - - - + + + + - + - 100663317 + 100663321 Xrm.Oss.FluentQuery.IFluentQuery`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::DatabaseLock(System.Boolean) - - - - + + + + - + - 100663318 + 100663322 System.Collections.Generic.List`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::Retrieve() - - - + + + - + - 100663319 + 100663323 System.Collections.Generic.List`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::RetrieveAll() - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - + + - + - 100663320 + 100663324 Xrm.Oss.FluentQuery.IFluentQuery`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::UniqueRecords(System.Boolean) - - - - + + + + - + - 100663321 + 100663325 Xrm.Oss.FluentQuery.IFluentQuery`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::Link(System.Action`1<Xrm.Oss.FluentQuery.IFluentLinkEntity>) - - - - - - + + + + + + - + - 100663322 + 100663326 Xrm.Oss.FluentQuery.IFluentQuery`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::Where(System.Action`1<Xrm.Oss.FluentQuery.IFluentFilterExpression>) - - - - - - + + + + + + - + + + + + 100663327 + System.Void Xrm.Oss.FluentQuery.FluentQuery`1::AddCondition(System.Action`1<Xrm.Oss.FluentQuery.IFluentConditionExpression>) + + + + + + + + + + + + + + 100663328 + System.Void Xrm.Oss.FluentQuery.FluentQuery`1::AddFilter(System.Action`1<Xrm.Oss.FluentQuery.IFluentFilterExpression>) + + + + + + + + + + - 100663323 + 100663329 Xrm.Oss.FluentQuery.IFluentQuery`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::Order(System.Action`1<Xrm.Oss.FluentQuery.IFluentOrderExpression>) - - - - - - + + + + + + - + - 100663324 + 100663330 Xrm.Oss.FluentQuery.IFluentQuery`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::PagingInfo(System.Action`1<Xrm.Oss.FluentQuery.IFluentPagingInfo>) - - - - - - + + + + + + - + - 100663325 + 100663331 Xrm.Oss.FluentQuery.IFluentQuery`1<T> Xrm.Oss.FluentQuery.FluentQuery`1::TotalRecordCount(System.Boolean) - - - - + + + + - + @@ -481,41 +526,41 @@ - 100663393 + 100663399 System.Void Xrm.Oss.FluentQuery.FluentQuery`1/<>c::.cctor() - + - 100663394 + 100663400 System.Void Xrm.Oss.FluentQuery.FluentQuery`1/<>c::.ctor() - + - 100663395 - T Xrm.Oss.FluentQuery.FluentQuery`1/<>c::<Retrieve>b__8_0(Microsoft.Xrm.Sdk.Entity) + 100663401 + T Xrm.Oss.FluentQuery.FluentQuery`1/<>c::<Retrieve>b__9_0(Microsoft.Xrm.Sdk.Entity) - + - + - 100663396 - T Xrm.Oss.FluentQuery.FluentQuery`1/<>c::<RetrieveAll>b__9_0(Microsoft.Xrm.Sdk.Entity) + 100663402 + T Xrm.Oss.FluentQuery.FluentQuery`1/<>c::<RetrieveAll>b__10_0(Microsoft.Xrm.Sdk.Entity) - + - + @@ -525,173 +570,173 @@ - 100663338 + 100663344 Xrm.Oss.FluentQuery.IFluentLinkEntitySetting Xrm.Oss.FluentQuery.FluentLinkEntity::get_With() - - - + + + - + - 100663337 + 100663343 System.Void Xrm.Oss.FluentQuery.FluentLinkEntity::.ctor() - - - - + + + + - + - 100663339 + 100663345 Xrm.Oss.FluentQuery.IFluentLinkEntity Xrm.Oss.FluentQuery.FluentLinkEntity::Alias(System.String) - - - - + + + + - + - 100663340 + 100663346 Xrm.Oss.FluentQuery.IFluentLinkEntity Xrm.Oss.FluentQuery.FluentLinkEntity::FromAttribute(System.String) - - - - + + + + - + - 100663341 + 100663347 Xrm.Oss.FluentQuery.IFluentLinkEntity Xrm.Oss.FluentQuery.FluentLinkEntity::FromEntity(System.String) - - - - + + + + - + - 100663342 + 100663348 Xrm.Oss.FluentQuery.IFluentLinkEntity Xrm.Oss.FluentQuery.FluentLinkEntity::IncludeColumns(System.String[]) - - - - + + + + - + - 100663343 + 100663349 Xrm.Oss.FluentQuery.IFluentLinkEntity Xrm.Oss.FluentQuery.FluentLinkEntity::Where(System.Action`1<Xrm.Oss.FluentQuery.IFluentFilterExpression>) - - - - - - + + + + + + - + - 100663344 + 100663350 Xrm.Oss.FluentQuery.IFluentLinkEntity Xrm.Oss.FluentQuery.FluentLinkEntity::Link(System.Action`1<Xrm.Oss.FluentQuery.IFluentLinkEntity>) - - - - - - + + + + + + - + - 100663345 + 100663351 Xrm.Oss.FluentQuery.IFluentLinkEntity Xrm.Oss.FluentQuery.FluentLinkEntity::LinkType(Microsoft.Xrm.Sdk.Query.JoinOperator) - - - - + + + + - + - 100663346 + 100663352 Xrm.Oss.FluentQuery.IFluentLinkEntity Xrm.Oss.FluentQuery.FluentLinkEntity::ToAttribute(System.String) - - - - + + + + - + - 100663347 + 100663353 Xrm.Oss.FluentQuery.IFluentLinkEntity Xrm.Oss.FluentQuery.FluentLinkEntity::ToEntity(System.String) - - - - + + + + - + - 100663348 + 100663354 Microsoft.Xrm.Sdk.Query.LinkEntity Xrm.Oss.FluentQuery.FluentLinkEntity::GetLinkEntity() - - - + + + - + @@ -701,89 +746,89 @@ - 100663354 + 100663360 Xrm.Oss.FluentQuery.IFluentFilterExpressionSetting Xrm.Oss.FluentQuery.FluentFilterExpression::get_With() - - - + + + - + - 100663353 + 100663359 System.Void Xrm.Oss.FluentQuery.FluentFilterExpression::.ctor() - - - - + + + + - + - 100663355 + 100663361 Xrm.Oss.FluentQuery.IFluentFilterExpression Xrm.Oss.FluentQuery.FluentFilterExpression::Operator(Microsoft.Xrm.Sdk.Query.LogicalOperator) - - - - + + + + - + - 100663356 + 100663362 Xrm.Oss.FluentQuery.IFluentFilterExpression Xrm.Oss.FluentQuery.FluentFilterExpression::Where(System.Action`1<Xrm.Oss.FluentQuery.IFluentFilterExpression>) - - - - - - + + + + + + - + - 100663357 + 100663363 Xrm.Oss.FluentQuery.IFluentFilterExpression Xrm.Oss.FluentQuery.FluentFilterExpression::Attribute(System.Action`1<Xrm.Oss.FluentQuery.IFluentConditionExpression>) - - - - - - + + + + + + - + - 100663358 + 100663364 Microsoft.Xrm.Sdk.Query.FilterExpression Xrm.Oss.FluentQuery.FluentFilterExpression::GetFilter() - - - + + + - + @@ -793,126 +838,126 @@ - 100663366 + 100663372 System.Void Xrm.Oss.FluentQuery.FluentConditionExpression::.ctor() - - - - + + + + - + - 100663367 + 100663373 Xrm.Oss.FluentQuery.IFluentConditionExpression Xrm.Oss.FluentQuery.FluentConditionExpression::Is(Microsoft.Xrm.Sdk.Query.ConditionOperator) - - - - + + + + - + - 100663368 + 100663374 Xrm.Oss.FluentQuery.IFluentConditionExpression Xrm.Oss.FluentQuery.FluentConditionExpression::Named(System.String) - - - - + + + + - + - 100663369 + 100663375 Xrm.Oss.FluentQuery.IFluentConditionExpression Xrm.Oss.FluentQuery.FluentConditionExpression::Of(System.String) - - - - + + + + - + - 100663370 + 100663376 Xrm.Oss.FluentQuery.IFluentConditionExpression Xrm.Oss.FluentQuery.FluentConditionExpression::To(System.Object) - - - + + + - + - 100663371 + 100663377 Xrm.Oss.FluentQuery.IFluentConditionExpression Xrm.Oss.FluentQuery.FluentConditionExpression::To(System.Object[]) - - - + + + - + - 100663372 + 100663378 Xrm.Oss.FluentQuery.IFluentConditionExpression Xrm.Oss.FluentQuery.FluentConditionExpression::Value(System.Object) - - - - + + + + - + - 100663373 + 100663379 Xrm.Oss.FluentQuery.IFluentConditionExpression Xrm.Oss.FluentQuery.FluentConditionExpression::Value(System.Object[]) - - - - + + + + - + - 100663374 + 100663380 Microsoft.Xrm.Sdk.Query.ConditionExpression Xrm.Oss.FluentQuery.FluentConditionExpression::GetCondition() - - - + + + - + @@ -922,72 +967,72 @@ - 100663378 + 100663384 System.Void Xrm.Oss.FluentQuery.FluentOrderExpression::.ctor() - - - - + + + + - + - 100663379 + 100663385 Xrm.Oss.FluentQuery.IFluentOrderExpression Xrm.Oss.FluentQuery.FluentOrderExpression::By(System.String) - - - - + + + + - + - 100663380 + 100663386 Xrm.Oss.FluentQuery.IFluentOrderExpression Xrm.Oss.FluentQuery.FluentOrderExpression::Ascending() - - - - + + + + - + - 100663381 + 100663387 Xrm.Oss.FluentQuery.IFluentOrderExpression Xrm.Oss.FluentQuery.FluentOrderExpression::Descending() - - - - + + + + - + - 100663382 + 100663388 Microsoft.Xrm.Sdk.Query.OrderExpression Xrm.Oss.FluentQuery.FluentOrderExpression::GetOrder() - - - + + + - + @@ -997,86 +1042,86 @@ - 100663387 + 100663393 System.Void Xrm.Oss.FluentQuery.FluentPagingInfo::.ctor() - - - - + + + + - + - 100663388 + 100663394 Xrm.Oss.FluentQuery.IFluentPagingInfo Xrm.Oss.FluentQuery.FluentPagingInfo::PageNumber(System.Int32) - - - - + + + + - + - 100663389 + 100663395 Xrm.Oss.FluentQuery.IFluentPagingInfo Xrm.Oss.FluentQuery.FluentPagingInfo::PageSize(System.Int32) - - - - + + + + - + - 100663390 + 100663396 Xrm.Oss.FluentQuery.IFluentPagingInfo Xrm.Oss.FluentQuery.FluentPagingInfo::PagingCookie(System.String) - - - - + + + + - + - 100663391 + 100663397 Xrm.Oss.FluentQuery.IFluentPagingInfo Xrm.Oss.FluentQuery.FluentPagingInfo::ReturnTotalRecordCount(System.Boolean) - - - - + + + + - + - 100663392 + 100663398 Microsoft.Xrm.Sdk.Query.PagingInfo Xrm.Oss.FluentQuery.FluentPagingInfo::GetPagingInfo() - - - + + + - + diff --git a/reports/Xrm.Oss.FluentQuery_FluentConditionExpression.htm b/reports/Xrm.Oss.FluentQuery_FluentConditionExpression.htm index 7ab72b2..085b3cc 100644 --- a/reports/Xrm.Oss.FluentQuery_FluentConditionExpression.htm +++ b/reports/Xrm.Oss.FluentQuery_FluentConditionExpression.htm @@ -20,7 +20,7 @@

Summary

Covered lines:33 Uncovered lines:0 Coverable lines:33 -Total lines:871 +Total lines:920 Line coverage:100% @@ -130,806 +130,855 @@

 84  85        /**  86         * <summary>87         * Returns the Query Expression that represents the current fluent query.87         * Adds all columns to the query. This is disadvised, specify the columns you need if possible.  88         * </summary>  89         */90        QueryExpression Expression { get; }90        IFluentQuery<T> IncludeAllColumns();  91  92        /**  93         * <summary>94         * Retrieves the first page for your query.94         * Returns the Query Expression that represents the current fluent query.  95         * </summary>96         * <returns>Records retrieved from your query.</returns>97         */98        List<T> Retrieve();99100        /**101         * <summary>102         * Retrieves all pages for your query.103         * </summary>104         * <returns>Records retrieved from your query.</returns>105         */106        List<T> RetrieveAll();107108        /**109         * <summary>110         * Use this for setting further options in your query.111         * </summary>96         */97        QueryExpression Expression { get; }9899        /**100         * <summary>101         * Retrieves the first page for your query.102         * </summary>103         * <returns>Records retrieved from your query.</returns>104         */105        List<T> Retrieve();106107        /**108         * <summary>109         * Retrieves all pages for your query.110         * </summary>111         * <returns>Records retrieved from your query.</returns>  112         */113        IFluentQuerySetting<T> With { get; }113        List<T> RetrieveAll();  114  115        /**  116         * <summary>117         * Adds a link to a connected entity.117         * Use this for setting further options in your query.  118         * </summary>119         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>120         */121        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);122123        /**124         * <summary>125         * Adds filter conditions to your query.126         * </summary>127         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>128         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>129         */130        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);131132        /**133         * <summary>134         * Adds an order expression to your query.135         * </summary>136         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>137         */138        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);139    }140141    public interface IFluentQuerySetting<T> where T : Entity142    {143        /**144         * <summary>145         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.146         * </summary>147         * <param name="topCount">Top X count of records to retrieve</param>148         */149        IFluentQuery<T> RecordCount(int? topCount);150151        /**152         * <summary>153         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi154         * </summary>155         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 156         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>157         */158        IFluentQuery<T> DatabaseLock(bool useLock = true);159160        /**161         * <summary>162         * Specifies whether duplicate records in your query will be filtered out or not.163         * </summary>164         * <param name="unique">True for only returning unique records, false otherwise</param>165         */166        IFluentQuery<T> UniqueRecords(bool unique = true);167168        /**169         * <summary>170         * Adds paging info to your query, such as page size, page number or paging cookie.171         * </summary>172         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>173         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>174         */175        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);176177        /**178         * <summary>179         * Specifies whether the total record count of your query results should be retrieved.180         * </summary>181         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>182         */183        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);184    }185186    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity187    {188        private QueryExpression _query;189        private IOrganizationService _service;119         */120        IFluentQuerySetting<T> With { get; }121122        /**123         * <summary>124         * Adds a link to a connected entity.125         * </summary>126         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>127         */128        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);129130        /**131         * <summary>132         * Adds filter conditions to your query.133         * </summary>134         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>135         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>136         */137        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);138139        /**140         * <summary>141         * Adds another condition to the top level filter expression.142         * </summary>143         * <param name="definition">The condition expression to add.</param>144         */145        void AddCondition(Action<IFluentConditionExpression> definition);146147        /**148         * <summary>149         * Adds a child filter to your top level filter.150         * </summary>151         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>152         */153        void AddFilter(Action<IFluentFilterExpression> definition);154155        /**156         * <summary>157         * Adds an order expression to your query.158         * </summary>159         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>160         */161        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);162    }163164    public interface IFluentQuerySetting<T> where T : Entity165    {166        /**167         * <summary>168         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.169         * </summary>170         * <param name="topCount">Top X count of records to retrieve</param>171         */172        IFluentQuery<T> RecordCount(int? topCount);173174        /**175         * <summary>176         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi177         * </summary>178         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 179         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>180         */181        IFluentQuery<T> DatabaseLock(bool useLock = true);182183        /**184         * <summary>185         * Specifies whether duplicate records in your query will be filtered out or not.186         * </summary>187         * <param name="unique">True for only returning unique records, false otherwise</param>188         */189        IFluentQuery<T> UniqueRecords(bool unique = true);  190191        public FluentQuery(string entityName, IOrganizationService service)192        {193            _query = new QueryExpression194            {195                EntityName = entityName,196                NoLock = true197            };198199            _service = service;200        }201202        public IFluentQuery<T> IncludeColumns(params string[] columns)203        {204            _query.ColumnSet.AddColumns(columns);205206            return this;207        }191        /**192         * <summary>193         * Adds paging info to your query, such as page size, page number or paging cookie.194         * </summary>195         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>196         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>197         */198        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);199200        /**201         * <summary>202         * Specifies whether the total record count of your query results should be retrieved.203         * </summary>204         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>205         */206        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);207    }  208209        public IFluentQuerySetting<T> With210        {211            get212            {213                return this;214            }215        }216217        public IFluentQuery<T> RecordCount(int? topCount)218        {219            _query.TopCount = topCount;220221            return this;222        }223224        public IFluentQuery<T> DatabaseLock(bool useLock = true)225        {226            _query.NoLock = !useLock;227228            return this;229        }230231        public List<T> Retrieve()232        {233            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())234                .ToList();235        }209    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity210    {211        private QueryExpression _query;212        private IOrganizationService _service;213214        public FluentQuery(string entityName, IOrganizationService service)215        {216            _query = new QueryExpression217            {218                EntityName = entityName,219                NoLock = true220            };221222            _service = service;223        }224225        public IFluentQuery<T> IncludeColumns(params string[] columns)226        {227            _query.ColumnSet.AllColumns = false;228            _query.ColumnSet.AddColumns(columns);229230            return this;231        }232233        public IFluentQuery<T> IncludeAllColumns()234        {235            _query.ColumnSet.AllColumns = true;  236237        public List<T> RetrieveAll()238        {239            var records = new List<T>();240241            var previousPageNumber = _query.PageInfo.PageNumber;242            var previousPagingCookie = _query.PageInfo.PagingCookie;243244            var moreRecords = false;245            var pageNumber = previousPageNumber;246            string pagingCookie = previousPagingCookie;237            return this;238        }239240        public IFluentQuerySetting<T> With241        {242            get243            {244                return this;245            }246        }  247248            do249            {250                _query.PageInfo.PageNumber = pageNumber;251                _query.PageInfo.PagingCookie = pagingCookie;252253                var response = _service.RetrieveMultiple(_query);254                var result = response.Entities.Select(e => e.ToEntity<T>())255                    .ToList();256257                records.AddRange(result);248        public IFluentQuery<T> RecordCount(int? topCount)249        {250            _query.TopCount = topCount;251252            return this;253        }254255        public IFluentQuery<T> DatabaseLock(bool useLock = true)256        {257            _query.NoLock = !useLock;  258259                moreRecords = response.MoreRecords;260                pageNumber++;261            }262            while (moreRecords);263264            _query.PageInfo.PageNumber = previousPageNumber;265            _query.PageInfo.PagingCookie = previousPagingCookie;266267            return records;268        }269270        public IFluentQuery<T> UniqueRecords(bool unique = true)271        {272            _query.Distinct = true;273274            return this;275        }276277        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)278        {279            var link = new FluentLinkEntity();280281            definition(link);282283            _query.LinkEntities.Add(link.GetLinkEntity());284285            return this;286        }259            return this;260        }261262        public List<T> Retrieve()263        {264            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())265                .ToList();266        }267268        public List<T> RetrieveAll()269        {270            var records = new List<T>();271272            var previousPageNumber = _query.PageInfo.PageNumber;273            var previousPagingCookie = _query.PageInfo.PagingCookie;274275            var moreRecords = false;276            var pageNumber = previousPageNumber;277            string pagingCookie = previousPagingCookie;278279            do280            {281                _query.PageInfo.PageNumber = pageNumber;282                _query.PageInfo.PagingCookie = pagingCookie;283284                var response = _service.RetrieveMultiple(_query);285                var result = response.Entities.Select(e => e.ToEntity<T>())286                    .ToList();  287288        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)289        {290            var filter = new FluentFilterExpression();291292            definition(filter);293294            _query.Criteria = filter.GetFilter();295296            return this;297        }298299        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)300        {301            var order = new FluentOrderExpression();302303            definition(order);288                records.AddRange(result);289290                moreRecords = response.MoreRecords;291                pageNumber++;292            }293            while (moreRecords);294295            _query.PageInfo.PageNumber = previousPageNumber;296            _query.PageInfo.PagingCookie = previousPagingCookie;297298            return records;299        }300301        public IFluentQuery<T> UniqueRecords(bool unique = true)302        {303            _query.Distinct = true;  304305            _query.Orders.Add(order.GetOrder());306307            return this;308        }309310        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)311        {312            var PagingInfo = new FluentPagingInfo();305            return this;306        }307308        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)309        {310            var link = new FluentLinkEntity();311312            definition(link);  313314            definition(PagingInfo);314            _query.LinkEntities.Add(link.GetLinkEntity());  315316            _query.PageInfo = PagingInfo.GetPagingInfo();317318            return this;319        }320321        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)322        {323            _query.PageInfo.ReturnTotalRecordCount = true;316            return this;317        }318319        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)320        {321            var filter = new FluentFilterExpression();322323            definition(filter);  324325            return this;326        }327328        public QueryExpression Expression329        {330            get331            {332                return _query;333            }334        }335    }336337    public interface IFluentLinkEntity338    {339        /**340         * <summary>341         * Logical name of entity that the link is created from.342         * </summary>343         * <param name="entityName">Entity Logical Name</param>344         */345        IFluentLinkEntity FromEntity(string entityName);346347        /**348         * <summary>349         * Logical name of attribute that the link is created from.350         * </summary>351         * <param name="attributeName">Attribute Logical Name</param>352         */353        IFluentLinkEntity FromAttribute(string attributeName);354355        /**356         * <summary>357         * Logical name of entity that the link is created to.358         * </summary>359         * <param name="entityName">Entity Logical Name</param>360         */361        IFluentLinkEntity ToEntity(string entityName);325            _query.Criteria = filter.GetFilter();326327            return this;328        }329330        public void AddCondition(Action<IFluentConditionExpression> definition)331        {332            var condition = new FluentConditionExpression();333334            definition(condition);335336            _query.Criteria.AddCondition(condition.GetCondition());337        }338339        public void AddFilter(Action<IFluentFilterExpression> definition)340        {341            var filter = new FluentFilterExpression();342343            definition(filter);344345            _query.Criteria.AddFilter(filter.GetFilter());346        }347348        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)349        {350            var order = new FluentOrderExpression();351352            definition(order);353354            _query.Orders.Add(order.GetOrder());355356            return this;357        }358359        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)360        {361            var PagingInfo = new FluentPagingInfo();  362363        /**364         * <summary>365         * Logical name of attribute that the link is created to.366         * </summary>367         * <param name="attributeName">Attribute Logical Name</param>368         */369        IFluentLinkEntity ToAttribute(string attributeName);370371        /**372         * <summary>373         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.374         * </summary>375         * <param name="columns">Params array of your columns.</param>376         */377        IFluentLinkEntity IncludeColumns(params string[] columns);378379        /**380        * <summary>381        * Use this for setting further options of your link.382        * </summary>383        */384        IFluentLinkEntitySetting With { get; }363            definition(PagingInfo);364365            _query.PageInfo = PagingInfo.GetPagingInfo();366367            return this;368        }369370        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)371        {372            _query.PageInfo.ReturnTotalRecordCount = true;373374            return this;375        }376377        public QueryExpression Expression378        {379            get380            {381                return _query;382            }383        }384    }  385386        /**387         * <summary>388         * Adds a nested link to this link.389         * </summary>390         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>391         */392        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);393394        /**395         * <summary>396         * Adds filter conditions to your link.397         * </summary>398         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>399         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>400         */401        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);402    }386    public interface IFluentLinkEntity387    {388        /**389         * <summary>390         * Logical name of entity that the link is created from.391         * </summary>392         * <param name="entityName">Entity Logical Name</param>393         */394        IFluentLinkEntity FromEntity(string entityName);395396        /**397         * <summary>398         * Logical name of attribute that the link is created from.399         * </summary>400         * <param name="attributeName">Attribute Logical Name</param>401         */402        IFluentLinkEntity FromAttribute(string attributeName);  403404    public interface IFluentLinkEntitySetting405    {406        /**407         * <summary>408         * Sets an alias for the results of this link entity.409         * </summary>410         * <param name="name">Alias to set in results.</param>411         */412        IFluentLinkEntity Alias(string name);413414        /**415         * <summary>Join type of this link.</summary>416         * <param name="joinOperator">Join type to use.</param>404        /**405         * <summary>406         * Logical name of entity that the link is created to.407         * </summary>408         * <param name="entityName">Entity Logical Name</param>409         */410        IFluentLinkEntity ToEntity(string entityName);411412        /**413         * <summary>414         * Logical name of attribute that the link is created to.415         * </summary>416         * <param name="attributeName">Attribute Logical Name</param>  417         */418        IFluentLinkEntity LinkType(JoinOperator joinOperator);419    }420421    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting422    {423        private LinkEntity _linkEntity;424425        public FluentLinkEntity()426        {427            _linkEntity = new LinkEntity428            {429                Columns = new ColumnSet()430            };431        }432433        public IFluentLinkEntitySetting With434        {435            get436            {437                return this;438            }439        }440441        public IFluentLinkEntity Alias(string name)442        {443            _linkEntity.EntityAlias = name;444445            return this;446        }447448        public IFluentLinkEntity FromAttribute(string attributeName)449        {450            _linkEntity.LinkFromAttributeName = attributeName;451452            return this;453        }454455        public IFluentLinkEntity FromEntity(string entityName)456        {457            _linkEntity.LinkFromEntityName = entityName;458459            return this;460        }461462        public IFluentLinkEntity IncludeColumns(params string[] columns)463        {464            _linkEntity.Columns.AddColumns(columns);465466            return this;467        }468469        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)470        {471            var filter = new FluentFilterExpression();472473            definition(filter);474475            _linkEntity.LinkCriteria = filter.GetFilter();476477            return this;478        }479480        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)481        {482            var link = new FluentLinkEntity();483484            definition(link);485486            _linkEntity.LinkEntities.Add(link.GetLinkEntity());487488            return this;489        }490491        public IFluentLinkEntity LinkType(JoinOperator joinOperator)492        {493            _linkEntity.JoinOperator = joinOperator;494495            return this;496        }497498        public IFluentLinkEntity ToAttribute(string attributeName)499        {500            _linkEntity.LinkToAttributeName = attributeName;501502            return this;503        }504505        public IFluentLinkEntity ToEntity(string entityName)506        {507            _linkEntity.LinkToEntityName = entityName;508509            return this;510        }511512        internal LinkEntity GetLinkEntity()513        {514            return _linkEntity;515        }516    }418        IFluentLinkEntity ToAttribute(string attributeName);419420        /**421         * <summary>422         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.423         * </summary>424         * <param name="columns">Params array of your columns.</param>425         */426        IFluentLinkEntity IncludeColumns(params string[] columns);427428        /**429        * <summary>430        * Use this for setting further options of your link.431        * </summary>432        */433        IFluentLinkEntitySetting With { get; }434435        /**436         * <summary>437         * Adds a nested link to this link.438         * </summary>439         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>440         */441        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);442443        /**444         * <summary>445         * Adds filter conditions to your link.446         * </summary>447         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>448         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>449         */450        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);451    }452453    public interface IFluentLinkEntitySetting454    {455        /**456         * <summary>457         * Sets an alias for the results of this link entity.458         * </summary>459         * <param name="name">Alias to set in results.</param>460         */461        IFluentLinkEntity Alias(string name);462463        /**464         * <summary>Join type of this link.</summary>465         * <param name="joinOperator">Join type to use.</param>466         */467        IFluentLinkEntity LinkType(JoinOperator joinOperator);468    }469470    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting471    {472        private LinkEntity _linkEntity;473474        public FluentLinkEntity()475        {476            _linkEntity = new LinkEntity477            {478                Columns = new ColumnSet()479            };480        }481482        public IFluentLinkEntitySetting With483        {484            get485            {486                return this;487            }488        }489490        public IFluentLinkEntity Alias(string name)491        {492            _linkEntity.EntityAlias = name;493494            return this;495        }496497        public IFluentLinkEntity FromAttribute(string attributeName)498        {499            _linkEntity.LinkFromAttributeName = attributeName;500501            return this;502        }503504        public IFluentLinkEntity FromEntity(string entityName)505        {506            _linkEntity.LinkFromEntityName = entityName;507508            return this;509        }510511        public IFluentLinkEntity IncludeColumns(params string[] columns)512        {513            _linkEntity.Columns.AddColumns(columns);514515            return this;516        }  517518    public interface IFluentFilterExpression519    {520        /**521        * <summary>522        * Use this for setting further options of your filter.523        * </summary>524        */525        IFluentFilterExpressionSetting With { get; }526527        /**528        * <summary>529        * Use this for adding a condition on an attribute to your filter.530        * </summary>531        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>532        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>533        */534        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);535536        /**537         * <summary>538         * Adds nested filter conditions to your filter.539         * </summary>540         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>541         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>542         */543        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);544    }545546    public interface IFluentFilterExpressionSetting547    {548        /**549         * <summary>550         * Sets the logical operator for chaining multiple conditions in this filter.551         * </summary>552         */553        IFluentFilterExpression Operator(LogicalOperator filterOperator);554    }555556    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting557    {558        private FilterExpression _filter;559560        public FluentFilterExpression()561        {562            _filter = new FilterExpression();563        }564565        public IFluentFilterExpressionSetting With566        {567            get568            {569                return this;570            }571        }572573        public IFluentFilterExpression Operator(LogicalOperator filterOperator)574        {575            _filter.FilterOperator = filterOperator;576577            return this;578        }579580        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)581        {582            var filter = new FluentFilterExpression();583584            definition(filter);585586            _filter.Filters.Add(filter.GetFilter());587588            return this;589        }590591        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)592        {593            var condition = new FluentConditionExpression();518        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)519        {520            var filter = new FluentFilterExpression();521522            definition(filter);523524            _linkEntity.LinkCriteria = filter.GetFilter();525526            return this;527        }528529        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)530        {531            var link = new FluentLinkEntity();532533            definition(link);534535            _linkEntity.LinkEntities.Add(link.GetLinkEntity());536537            return this;538        }539540        public IFluentLinkEntity LinkType(JoinOperator joinOperator)541        {542            _linkEntity.JoinOperator = joinOperator;543544            return this;545        }546547        public IFluentLinkEntity ToAttribute(string attributeName)548        {549            _linkEntity.LinkToAttributeName = attributeName;550551            return this;552        }553554        public IFluentLinkEntity ToEntity(string entityName)555        {556            _linkEntity.LinkToEntityName = entityName;557558            return this;559        }560561        internal LinkEntity GetLinkEntity()562        {563            return _linkEntity;564        }565    }566567    public interface IFluentFilterExpression568    {569        /**570        * <summary>571        * Use this for setting further options of your filter.572        * </summary>573        */574        IFluentFilterExpressionSetting With { get; }575576        /**577        * <summary>578        * Use this for adding a condition on an attribute to your filter.579        * </summary>580        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>581        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>582        */583        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);584585        /**586         * <summary>587         * Adds nested filter conditions to your filter.588         * </summary>589         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>590         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>591         */592        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);593    }  594595            definition(condition);596597            _filter.Conditions.Add(condition.GetCondition());598599            return this;600        }601602        internal FilterExpression GetFilter()603        {604            return _filter;605        }606    }607608    public interface IFluentConditionExpression609    {610        /**611         * <summary>612         * Set the entity name that your condition attribute targets, if it is not the main entity.613         * </summary>614         * <param name="entityName">Entity Logical Name</param>615         */616        IFluentConditionExpression Of(string entityName);617618        /**619         * <summary>620         * Set the logical name of the attribute that your condition targets.621         * </summary>622         * <param name="attributeName">Attribute logical name</param>623         */624        IFluentConditionExpression Named(string attributeName);595    public interface IFluentFilterExpressionSetting596    {597        /**598         * <summary>599         * Sets the logical operator for chaining multiple conditions in this filter.600         * </summary>601         */602        IFluentFilterExpression Operator(LogicalOperator filterOperator);603    }604605    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting606    {607        private FilterExpression _filter;608609        public FluentFilterExpression()610        {611            _filter = new FilterExpression();612        }613614        public IFluentFilterExpressionSetting With615        {616            get617            {618                return this;619            }620        }621622        public IFluentFilterExpression Operator(LogicalOperator filterOperator)623        {624            _filter.FilterOperator = filterOperator;  625626        /**627         * <summary>628         * Set the condition operator for your condition.629         * </summary>630         * <param name="conditionOperator">Condition Operator Enum</param>631         */632        IFluentConditionExpression Is(ConditionOperator conditionOperator);633634        /**635         * <summary>636         * Sets the value for the condition.637         * </summary>638         * <param name="value">Single object, use object array overload if necessary.</param>639         */640        IFluentConditionExpression Value(object value);641642        /**643         * <summary>644         * Sets the values for the condition.645         * </summary>646         * <param name="value">Object array, use object overload if necessary.</param>647         */648        IFluentConditionExpression Value(params object[] value);649650        /**651         * <summary>652         * Alias for Value, provides better readability on Equal conditions.653         * Sets the value for the condition.654         * </summary>655         * <param name="value">Single object, use object array overload if necessary.</param>656         */657        IFluentConditionExpression To(object value);658626            return this;627        }628629        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)630        {631            var filter = new FluentFilterExpression();632633            definition(filter);634635            _filter.Filters.Add(filter.GetFilter());636637            return this;638        }639640        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)641        {642            var condition = new FluentConditionExpression();643644            definition(condition);645646            _filter.Conditions.Add(condition.GetCondition());647648            return this;649        }650651        internal FilterExpression GetFilter()652        {653            return _filter;654        }655    }656657    public interface IFluentConditionExpression658    {  659        /**  660         * <summary>661         * Alias for Value, provides better readability on Equal conditions.662         * Sets the values for the condition.663         * </summary>664         * <param name="value">Object array, use object overload if necessary.</param>665         */666        IFluentConditionExpression To(params object[] value);667    }668669    public class FluentConditionExpression : IFluentConditionExpression670    {671        private ConditionExpression _condition;672 - 7673        public FluentConditionExpression() - 7674        { - 7675            _condition = new ConditionExpression(); - 7676        }677678        public IFluentConditionExpression Is(ConditionOperator conditionOperator) - 7679        { - 7680            _condition.Operator = conditionOperator;681 - 7682            return this; - 7683        }684685        public IFluentConditionExpression Named(string attributeName) - 7686        { - 7687            _condition.AttributeName = attributeName;688 - 7689            return this; - 7690        }691692        public IFluentConditionExpression Of(string entityName) - 5693        { - 5694            _condition.EntityName = entityName;695 - 5696            return this; - 5697        }661         * Set the entity name that your condition attribute targets, if it is not the main entity.662         * </summary>663         * <param name="entityName">Entity Logical Name</param>664         */665        IFluentConditionExpression Of(string entityName);666667        /**668         * <summary>669         * Set the logical name of the attribute that your condition targets.670         * </summary>671         * <param name="attributeName">Attribute logical name</param>672         */673        IFluentConditionExpression Named(string attributeName);674675        /**676         * <summary>677         * Set the condition operator for your condition.678         * </summary>679         * <param name="conditionOperator">Condition Operator Enum</param>680         */681        IFluentConditionExpression Is(ConditionOperator conditionOperator);682683        /**684         * <summary>685         * Sets the value for the condition.686         * </summary>687         * <param name="value">Single object, use object array overload if necessary.</param>688         */689        IFluentConditionExpression Value(object value);690691        /**692         * <summary>693         * Sets the values for the condition.694         * </summary>695         * <param name="value">Object array, use object overload if necessary.</param>696         */697        IFluentConditionExpression Value(params object[] value);  698699        public IFluentConditionExpression To(object value) - 1700        { - 1701            return Value(value); - 1702        }703704        public IFluentConditionExpression To(params object[] value) - 1705        { - 1706            return Value(value); - 1707        }708709        public IFluentConditionExpression Value(object value) - 4710        { - 4711            _condition.Values.Add(value);712 - 4713            return this; - 4714        }715716        public IFluentConditionExpression Value(params object[] value) - 2717        { - 2718            _condition.Values.AddRange(value);719 - 2720            return this; - 2721        }722723        internal ConditionExpression GetCondition () - 7724        { - 7725            return _condition; - 7726        }727    }728729    public interface IFluentOrderExpression730    {731        /**732         * <summary>733         * Set the attribute name to order by.734         * </summary>735         * <param name="attributeName">Attribute logical name</param>736         */737        IFluentOrderExpression By(string attributeName);738739        /**740         * <summary>741         * Sets the sort order to be ascending.742         * </summary>743         */744        IFluentOrderExpression Ascending();745746        /**747         * <summary>748         * Sets the sort order to be descending.749         * </summary>750         */751        IFluentOrderExpression Descending();752    }753754    public class FluentOrderExpression : IFluentOrderExpression755    {756        private OrderExpression _order;699        /**700         * <summary>701         * Alias for Value, provides better readability on Equal conditions.702         * Sets the value for the condition.703         * </summary>704         * <param name="value">Single object, use object array overload if necessary.</param>705         */706        IFluentConditionExpression To(object value);707708        /**709         * <summary>710         * Alias for Value, provides better readability on Equal conditions.711         * Sets the values for the condition.712         * </summary>713         * <param name="value">Object array, use object overload if necessary.</param>714         */715        IFluentConditionExpression To(params object[] value);716    }717718    public class FluentConditionExpression : IFluentConditionExpression719    {720        private ConditionExpression _condition;721 + 12722        public FluentConditionExpression() + 12723        { + 12724            _condition = new ConditionExpression(); + 12725        }726727        public IFluentConditionExpression Is(ConditionOperator conditionOperator) + 12728        { + 12729            _condition.Operator = conditionOperator;730 + 12731            return this; + 12732        }733734        public IFluentConditionExpression Named(string attributeName) + 12735        { + 12736            _condition.AttributeName = attributeName;737 + 12738            return this; + 12739        }740741        public IFluentConditionExpression Of(string entityName) + 7742        { + 7743            _condition.EntityName = entityName;744 + 7745            return this; + 7746        }747748        public IFluentConditionExpression To(object value) + 1749        { + 1750            return Value(value); + 1751        }752753        public IFluentConditionExpression To(params object[] value) + 1754        { + 1755            return Value(value); + 1756        }  757758        public FluentOrderExpression ()759        {760            _order = new OrderExpression();761        }762763        public IFluentOrderExpression By(string attributeName)764        {765            _order.AttributeName = attributeName;766767            return this;768        }769770        public IFluentOrderExpression Ascending()771        {772            _order.OrderType = OrderType.Ascending;773774            return this;775        }776777        public IFluentOrderExpression Descending()778        {779            _order.OrderType = OrderType.Descending;780781            return this;782        }783784        internal OrderExpression GetOrder()785        {786            return _order;787        }788    }789790    public interface IFluentPagingInfo791    {792        /**793         * <summary>794         * Set the page number to retrieve. Is set to 1 by default.795         * </summary>796         * <param name="number">Number of the page, starts at 1.</param>797         */798        IFluentPagingInfo PageNumber(int number);799800        /**801         * <summary>802         * Set the paging cookie for retrieving records from pages after the first.803         * </summary>804         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>805         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>806         */807        IFluentPagingInfo PagingCookie(string pagingCookie);808809        /**810         * <summary>811         * Set the size of each page.812         * </summary>813         * <param name="number">Number of records to return per page.</param>814         */815        IFluentPagingInfo PageSize(int number);816817        /**818         * <summary>819         * Specifies whether the total record count of your query results should be retrieved.820         * </summary>821         * <param name="returnTotal">True for returning total record count, false otherwise.</param>822         */823        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);824    }758        public IFluentConditionExpression Value(object value) + 6759        { + 6760            _condition.Values.Add(value);761 + 6762            return this; + 6763        }764765        public IFluentConditionExpression Value(params object[] value) + 2766        { + 2767            _condition.Values.AddRange(value);768 + 2769            return this; + 2770        }771772        internal ConditionExpression GetCondition () + 12773        { + 12774            return _condition; + 12775        }776    }777778    public interface IFluentOrderExpression779    {780        /**781         * <summary>782         * Set the attribute name to order by.783         * </summary>784         * <param name="attributeName">Attribute logical name</param>785         */786        IFluentOrderExpression By(string attributeName);787788        /**789         * <summary>790         * Sets the sort order to be ascending.791         * </summary>792         */793        IFluentOrderExpression Ascending();794795        /**796         * <summary>797         * Sets the sort order to be descending.798         * </summary>799         */800        IFluentOrderExpression Descending();801    }802803    public class FluentOrderExpression : IFluentOrderExpression804    {805        private OrderExpression _order;806807        public FluentOrderExpression ()808        {809            _order = new OrderExpression();810        }811812        public IFluentOrderExpression By(string attributeName)813        {814            _order.AttributeName = attributeName;815816            return this;817        }818819        public IFluentOrderExpression Ascending()820        {821            _order.OrderType = OrderType.Ascending;822823            return this;824        }  825826    public class FluentPagingInfo : IFluentPagingInfo827    {828        private PagingInfo _pagingInfo;826        public IFluentOrderExpression Descending()827        {828            _order.OrderType = OrderType.Descending;  829830        public FluentPagingInfo()831        {832            _pagingInfo = new PagingInfo833            {834                PageNumber = 1835            };830            return this;831        }832833        internal OrderExpression GetOrder()834        {835            return _order;  836        }837838        public IFluentPagingInfo PageNumber(int number)839        {840            _pagingInfo.PageNumber = number;841842            return this;843        }844845        public IFluentPagingInfo PageSize(int number)846        {847            _pagingInfo.Count = number;837    }838839    public interface IFluentPagingInfo840    {841        /**842         * <summary>843         * Set the page number to retrieve. Is set to 1 by default.844         * </summary>845         * <param name="number">Number of the page, starts at 1.</param>846         */847        IFluentPagingInfo PageNumber(int number);  848849            return this;850        }851852        public IFluentPagingInfo PagingCookie(string pagingCookie)853        {854            _pagingInfo.PagingCookie = pagingCookie;855856            return this;857        }858859        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)860        {861            _pagingInfo.ReturnTotalRecordCount = returnTotal;862863            return this;864        }849        /**850         * <summary>851         * Set the paging cookie for retrieving records from pages after the first.852         * </summary>853         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>854         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>855         */856        IFluentPagingInfo PagingCookie(string pagingCookie);857858        /**859         * <summary>860         * Set the size of each page.861         * </summary>862         * <param name="number">Number of records to return per page.</param>863         */864        IFluentPagingInfo PageSize(int number);  865866        public PagingInfo GetPagingInfo()867        {868            return _pagingInfo;869        }870    }871}866        /**867         * <summary>868         * Specifies whether the total record count of your query results should be retrieved.869         * </summary>870         * <param name="returnTotal">True for returning total record count, false otherwise.</param>871         */872        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);873    }874875    public class FluentPagingInfo : IFluentPagingInfo876    {877        private PagingInfo _pagingInfo;878879        public FluentPagingInfo()880        {881            _pagingInfo = new PagingInfo882            {883                PageNumber = 1884            };885        }886887        public IFluentPagingInfo PageNumber(int number)888        {889            _pagingInfo.PageNumber = number;890891            return this;892        }893894        public IFluentPagingInfo PageSize(int number)895        {896            _pagingInfo.Count = number;897898            return this;899        }900901        public IFluentPagingInfo PagingCookie(string pagingCookie)902        {903            _pagingInfo.PagingCookie = pagingCookie;904905            return this;906        }907908        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)909        {910            _pagingInfo.ReturnTotalRecordCount = returnTotal;911912            return this;913        }914915        public PagingInfo GetPagingInfo()916        {917            return _pagingInfo;918        }919    }920} - + diff --git a/reports/Xrm.Oss.FluentQuery_FluentFilterExpression.htm b/reports/Xrm.Oss.FluentQuery_FluentFilterExpression.htm index 9bcd8cb..df49b01 100644 --- a/reports/Xrm.Oss.FluentQuery_FluentFilterExpression.htm +++ b/reports/Xrm.Oss.FluentQuery_FluentFilterExpression.htm @@ -20,7 +20,7 @@

Summary

Covered lines:26 Uncovered lines:0 Coverable lines:26 -Total lines:871 +Total lines:920 Line coverage:100% @@ -126,803 +126,852 @@

 84  85        /**  86         * <summary>87         * Returns the Query Expression that represents the current fluent query.87         * Adds all columns to the query. This is disadvised, specify the columns you need if possible.  88         * </summary>  89         */90        QueryExpression Expression { get; }90        IFluentQuery<T> IncludeAllColumns();  91  92        /**  93         * <summary>94         * Retrieves the first page for your query.94         * Returns the Query Expression that represents the current fluent query.  95         * </summary>96         * <returns>Records retrieved from your query.</returns>97         */98        List<T> Retrieve();99100        /**101         * <summary>102         * Retrieves all pages for your query.103         * </summary>104         * <returns>Records retrieved from your query.</returns>105         */106        List<T> RetrieveAll();107108        /**109         * <summary>110         * Use this for setting further options in your query.111         * </summary>96         */97        QueryExpression Expression { get; }9899        /**100         * <summary>101         * Retrieves the first page for your query.102         * </summary>103         * <returns>Records retrieved from your query.</returns>104         */105        List<T> Retrieve();106107        /**108         * <summary>109         * Retrieves all pages for your query.110         * </summary>111         * <returns>Records retrieved from your query.</returns>  112         */113        IFluentQuerySetting<T> With { get; }113        List<T> RetrieveAll();  114  115        /**  116         * <summary>117         * Adds a link to a connected entity.117         * Use this for setting further options in your query.  118         * </summary>119         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>120         */121        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);122123        /**124         * <summary>125         * Adds filter conditions to your query.126         * </summary>127         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>128         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>129         */130        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);131132        /**133         * <summary>134         * Adds an order expression to your query.135         * </summary>136         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>137         */138        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);139    }140141    public interface IFluentQuerySetting<T> where T : Entity142    {143        /**144         * <summary>145         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.146         * </summary>147         * <param name="topCount">Top X count of records to retrieve</param>148         */149        IFluentQuery<T> RecordCount(int? topCount);150151        /**152         * <summary>153         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi154         * </summary>155         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 156         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>157         */158        IFluentQuery<T> DatabaseLock(bool useLock = true);159160        /**161         * <summary>162         * Specifies whether duplicate records in your query will be filtered out or not.163         * </summary>164         * <param name="unique">True for only returning unique records, false otherwise</param>165         */166        IFluentQuery<T> UniqueRecords(bool unique = true);167168        /**169         * <summary>170         * Adds paging info to your query, such as page size, page number or paging cookie.171         * </summary>172         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>173         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>174         */175        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);176177        /**178         * <summary>179         * Specifies whether the total record count of your query results should be retrieved.180         * </summary>181         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>182         */183        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);184    }185186    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity187    {188        private QueryExpression _query;189        private IOrganizationService _service;119         */120        IFluentQuerySetting<T> With { get; }121122        /**123         * <summary>124         * Adds a link to a connected entity.125         * </summary>126         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>127         */128        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);129130        /**131         * <summary>132         * Adds filter conditions to your query.133         * </summary>134         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>135         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>136         */137        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);138139        /**140         * <summary>141         * Adds another condition to the top level filter expression.142         * </summary>143         * <param name="definition">The condition expression to add.</param>144         */145        void AddCondition(Action<IFluentConditionExpression> definition);146147        /**148         * <summary>149         * Adds a child filter to your top level filter.150         * </summary>151         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>152         */153        void AddFilter(Action<IFluentFilterExpression> definition);154155        /**156         * <summary>157         * Adds an order expression to your query.158         * </summary>159         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>160         */161        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);162    }163164    public interface IFluentQuerySetting<T> where T : Entity165    {166        /**167         * <summary>168         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.169         * </summary>170         * <param name="topCount">Top X count of records to retrieve</param>171         */172        IFluentQuery<T> RecordCount(int? topCount);173174        /**175         * <summary>176         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi177         * </summary>178         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 179         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>180         */181        IFluentQuery<T> DatabaseLock(bool useLock = true);182183        /**184         * <summary>185         * Specifies whether duplicate records in your query will be filtered out or not.186         * </summary>187         * <param name="unique">True for only returning unique records, false otherwise</param>188         */189        IFluentQuery<T> UniqueRecords(bool unique = true);  190191        public FluentQuery(string entityName, IOrganizationService service)192        {193            _query = new QueryExpression194            {195                EntityName = entityName,196                NoLock = true197            };198199            _service = service;200        }201202        public IFluentQuery<T> IncludeColumns(params string[] columns)203        {204            _query.ColumnSet.AddColumns(columns);205206            return this;207        }191        /**192         * <summary>193         * Adds paging info to your query, such as page size, page number or paging cookie.194         * </summary>195         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>196         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>197         */198        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);199200        /**201         * <summary>202         * Specifies whether the total record count of your query results should be retrieved.203         * </summary>204         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>205         */206        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);207    }  208209        public IFluentQuerySetting<T> With210        {211            get212            {213                return this;214            }215        }216217        public IFluentQuery<T> RecordCount(int? topCount)218        {219            _query.TopCount = topCount;220221            return this;222        }223224        public IFluentQuery<T> DatabaseLock(bool useLock = true)225        {226            _query.NoLock = !useLock;227228            return this;229        }230231        public List<T> Retrieve()232        {233            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())234                .ToList();235        }209    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity210    {211        private QueryExpression _query;212        private IOrganizationService _service;213214        public FluentQuery(string entityName, IOrganizationService service)215        {216            _query = new QueryExpression217            {218                EntityName = entityName,219                NoLock = true220            };221222            _service = service;223        }224225        public IFluentQuery<T> IncludeColumns(params string[] columns)226        {227            _query.ColumnSet.AllColumns = false;228            _query.ColumnSet.AddColumns(columns);229230            return this;231        }232233        public IFluentQuery<T> IncludeAllColumns()234        {235            _query.ColumnSet.AllColumns = true;  236237        public List<T> RetrieveAll()238        {239            var records = new List<T>();240241            var previousPageNumber = _query.PageInfo.PageNumber;242            var previousPagingCookie = _query.PageInfo.PagingCookie;243244            var moreRecords = false;245            var pageNumber = previousPageNumber;246            string pagingCookie = previousPagingCookie;237            return this;238        }239240        public IFluentQuerySetting<T> With241        {242            get243            {244                return this;245            }246        }  247248            do249            {250                _query.PageInfo.PageNumber = pageNumber;251                _query.PageInfo.PagingCookie = pagingCookie;252253                var response = _service.RetrieveMultiple(_query);254                var result = response.Entities.Select(e => e.ToEntity<T>())255                    .ToList();256257                records.AddRange(result);248        public IFluentQuery<T> RecordCount(int? topCount)249        {250            _query.TopCount = topCount;251252            return this;253        }254255        public IFluentQuery<T> DatabaseLock(bool useLock = true)256        {257            _query.NoLock = !useLock;  258259                moreRecords = response.MoreRecords;260                pageNumber++;261            }262            while (moreRecords);263264            _query.PageInfo.PageNumber = previousPageNumber;265            _query.PageInfo.PagingCookie = previousPagingCookie;266267            return records;268        }269270        public IFluentQuery<T> UniqueRecords(bool unique = true)271        {272            _query.Distinct = true;273274            return this;275        }276277        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)278        {279            var link = new FluentLinkEntity();280281            definition(link);282283            _query.LinkEntities.Add(link.GetLinkEntity());284285            return this;286        }259            return this;260        }261262        public List<T> Retrieve()263        {264            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())265                .ToList();266        }267268        public List<T> RetrieveAll()269        {270            var records = new List<T>();271272            var previousPageNumber = _query.PageInfo.PageNumber;273            var previousPagingCookie = _query.PageInfo.PagingCookie;274275            var moreRecords = false;276            var pageNumber = previousPageNumber;277            string pagingCookie = previousPagingCookie;278279            do280            {281                _query.PageInfo.PageNumber = pageNumber;282                _query.PageInfo.PagingCookie = pagingCookie;283284                var response = _service.RetrieveMultiple(_query);285                var result = response.Entities.Select(e => e.ToEntity<T>())286                    .ToList();  287288        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)289        {290            var filter = new FluentFilterExpression();291292            definition(filter);293294            _query.Criteria = filter.GetFilter();295296            return this;297        }298299        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)300        {301            var order = new FluentOrderExpression();302303            definition(order);288                records.AddRange(result);289290                moreRecords = response.MoreRecords;291                pageNumber++;292            }293            while (moreRecords);294295            _query.PageInfo.PageNumber = previousPageNumber;296            _query.PageInfo.PagingCookie = previousPagingCookie;297298            return records;299        }300301        public IFluentQuery<T> UniqueRecords(bool unique = true)302        {303            _query.Distinct = true;  304305            _query.Orders.Add(order.GetOrder());306307            return this;308        }309310        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)311        {312            var PagingInfo = new FluentPagingInfo();305            return this;306        }307308        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)309        {310            var link = new FluentLinkEntity();311312            definition(link);  313314            definition(PagingInfo);314            _query.LinkEntities.Add(link.GetLinkEntity());  315316            _query.PageInfo = PagingInfo.GetPagingInfo();317318            return this;319        }320321        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)322        {323            _query.PageInfo.ReturnTotalRecordCount = true;316            return this;317        }318319        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)320        {321            var filter = new FluentFilterExpression();322323            definition(filter);  324325            return this;326        }327328        public QueryExpression Expression329        {330            get331            {332                return _query;333            }334        }335    }336337    public interface IFluentLinkEntity338    {339        /**340         * <summary>341         * Logical name of entity that the link is created from.342         * </summary>343         * <param name="entityName">Entity Logical Name</param>344         */345        IFluentLinkEntity FromEntity(string entityName);346347        /**348         * <summary>349         * Logical name of attribute that the link is created from.350         * </summary>351         * <param name="attributeName">Attribute Logical Name</param>352         */353        IFluentLinkEntity FromAttribute(string attributeName);354355        /**356         * <summary>357         * Logical name of entity that the link is created to.358         * </summary>359         * <param name="entityName">Entity Logical Name</param>360         */361        IFluentLinkEntity ToEntity(string entityName);325            _query.Criteria = filter.GetFilter();326327            return this;328        }329330        public void AddCondition(Action<IFluentConditionExpression> definition)331        {332            var condition = new FluentConditionExpression();333334            definition(condition);335336            _query.Criteria.AddCondition(condition.GetCondition());337        }338339        public void AddFilter(Action<IFluentFilterExpression> definition)340        {341            var filter = new FluentFilterExpression();342343            definition(filter);344345            _query.Criteria.AddFilter(filter.GetFilter());346        }347348        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)349        {350            var order = new FluentOrderExpression();351352            definition(order);353354            _query.Orders.Add(order.GetOrder());355356            return this;357        }358359        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)360        {361            var PagingInfo = new FluentPagingInfo();  362363        /**364         * <summary>365         * Logical name of attribute that the link is created to.366         * </summary>367         * <param name="attributeName">Attribute Logical Name</param>368         */369        IFluentLinkEntity ToAttribute(string attributeName);370371        /**372         * <summary>373         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.374         * </summary>375         * <param name="columns">Params array of your columns.</param>376         */377        IFluentLinkEntity IncludeColumns(params string[] columns);378379        /**380        * <summary>381        * Use this for setting further options of your link.382        * </summary>383        */384        IFluentLinkEntitySetting With { get; }363            definition(PagingInfo);364365            _query.PageInfo = PagingInfo.GetPagingInfo();366367            return this;368        }369370        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)371        {372            _query.PageInfo.ReturnTotalRecordCount = true;373374            return this;375        }376377        public QueryExpression Expression378        {379            get380            {381                return _query;382            }383        }384    }  385386        /**387         * <summary>388         * Adds a nested link to this link.389         * </summary>390         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>391         */392        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);393394        /**395         * <summary>396         * Adds filter conditions to your link.397         * </summary>398         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>399         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>400         */401        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);402    }386    public interface IFluentLinkEntity387    {388        /**389         * <summary>390         * Logical name of entity that the link is created from.391         * </summary>392         * <param name="entityName">Entity Logical Name</param>393         */394        IFluentLinkEntity FromEntity(string entityName);395396        /**397         * <summary>398         * Logical name of attribute that the link is created from.399         * </summary>400         * <param name="attributeName">Attribute Logical Name</param>401         */402        IFluentLinkEntity FromAttribute(string attributeName);  403404    public interface IFluentLinkEntitySetting405    {406        /**407         * <summary>408         * Sets an alias for the results of this link entity.409         * </summary>410         * <param name="name">Alias to set in results.</param>411         */412        IFluentLinkEntity Alias(string name);413414        /**415         * <summary>Join type of this link.</summary>416         * <param name="joinOperator">Join type to use.</param>404        /**405         * <summary>406         * Logical name of entity that the link is created to.407         * </summary>408         * <param name="entityName">Entity Logical Name</param>409         */410        IFluentLinkEntity ToEntity(string entityName);411412        /**413         * <summary>414         * Logical name of attribute that the link is created to.415         * </summary>416         * <param name="attributeName">Attribute Logical Name</param>  417         */418        IFluentLinkEntity LinkType(JoinOperator joinOperator);419    }420421    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting422    {423        private LinkEntity _linkEntity;424425        public FluentLinkEntity()426        {427            _linkEntity = new LinkEntity428            {429                Columns = new ColumnSet()430            };431        }432433        public IFluentLinkEntitySetting With434        {435            get436            {437                return this;438            }439        }440441        public IFluentLinkEntity Alias(string name)442        {443            _linkEntity.EntityAlias = name;444445            return this;446        }447448        public IFluentLinkEntity FromAttribute(string attributeName)449        {450            _linkEntity.LinkFromAttributeName = attributeName;451452            return this;453        }454455        public IFluentLinkEntity FromEntity(string entityName)456        {457            _linkEntity.LinkFromEntityName = entityName;458459            return this;460        }461462        public IFluentLinkEntity IncludeColumns(params string[] columns)463        {464            _linkEntity.Columns.AddColumns(columns);465466            return this;467        }468469        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)470        {471            var filter = new FluentFilterExpression();472473            definition(filter);474475            _linkEntity.LinkCriteria = filter.GetFilter();476477            return this;478        }479480        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)481        {482            var link = new FluentLinkEntity();483484            definition(link);485486            _linkEntity.LinkEntities.Add(link.GetLinkEntity());487488            return this;489        }490491        public IFluentLinkEntity LinkType(JoinOperator joinOperator)492        {493            _linkEntity.JoinOperator = joinOperator;494495            return this;496        }497498        public IFluentLinkEntity ToAttribute(string attributeName)499        {500            _linkEntity.LinkToAttributeName = attributeName;501502            return this;503        }504505        public IFluentLinkEntity ToEntity(string entityName)506        {507            _linkEntity.LinkToEntityName = entityName;508509            return this;510        }511512        internal LinkEntity GetLinkEntity()513        {514            return _linkEntity;515        }516    }418        IFluentLinkEntity ToAttribute(string attributeName);419420        /**421         * <summary>422         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.423         * </summary>424         * <param name="columns">Params array of your columns.</param>425         */426        IFluentLinkEntity IncludeColumns(params string[] columns);427428        /**429        * <summary>430        * Use this for setting further options of your link.431        * </summary>432        */433        IFluentLinkEntitySetting With { get; }434435        /**436         * <summary>437         * Adds a nested link to this link.438         * </summary>439         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>440         */441        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);442443        /**444         * <summary>445         * Adds filter conditions to your link.446         * </summary>447         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>448         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>449         */450        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);451    }452453    public interface IFluentLinkEntitySetting454    {455        /**456         * <summary>457         * Sets an alias for the results of this link entity.458         * </summary>459         * <param name="name">Alias to set in results.</param>460         */461        IFluentLinkEntity Alias(string name);462463        /**464         * <summary>Join type of this link.</summary>465         * <param name="joinOperator">Join type to use.</param>466         */467        IFluentLinkEntity LinkType(JoinOperator joinOperator);468    }469470    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting471    {472        private LinkEntity _linkEntity;473474        public FluentLinkEntity()475        {476            _linkEntity = new LinkEntity477            {478                Columns = new ColumnSet()479            };480        }481482        public IFluentLinkEntitySetting With483        {484            get485            {486                return this;487            }488        }489490        public IFluentLinkEntity Alias(string name)491        {492            _linkEntity.EntityAlias = name;493494            return this;495        }496497        public IFluentLinkEntity FromAttribute(string attributeName)498        {499            _linkEntity.LinkFromAttributeName = attributeName;500501            return this;502        }503504        public IFluentLinkEntity FromEntity(string entityName)505        {506            _linkEntity.LinkFromEntityName = entityName;507508            return this;509        }510511        public IFluentLinkEntity IncludeColumns(params string[] columns)512        {513            _linkEntity.Columns.AddColumns(columns);514515            return this;516        }  517518    public interface IFluentFilterExpression519    {520        /**521        * <summary>522        * Use this for setting further options of your filter.523        * </summary>524        */525        IFluentFilterExpressionSetting With { get; }526527        /**528        * <summary>529        * Use this for adding a condition on an attribute to your filter.530        * </summary>531        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>532        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>533        */534        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);535536        /**537         * <summary>538         * Adds nested filter conditions to your filter.539         * </summary>540         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>541         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>542         */543        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);544    }545546    public interface IFluentFilterExpressionSetting547    {548        /**549         * <summary>550         * Sets the logical operator for chaining multiple conditions in this filter.551         * </summary>552         */553        IFluentFilterExpression Operator(LogicalOperator filterOperator);554    }555556    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting557    {558        private FilterExpression _filter;559 - 6560        public FluentFilterExpression() - 6561        { - 6562            _filter = new FilterExpression(); - 6563        }564565        public IFluentFilterExpressionSetting With566        {567            get - 4568            { - 4569                return this; - 4570            }571        }572573        public IFluentFilterExpression Operator(LogicalOperator filterOperator) - 4574        { - 4575            _filter.FilterOperator = filterOperator;576 - 4577            return this; - 4578        }579580        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition) - 1581        { - 1582            var filter = new FluentFilterExpression();583 - 1584            definition(filter);585 - 1586            _filter.Filters.Add(filter.GetFilter());587 - 1588            return this; - 1589        }590591        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition) - 7592        { - 7593            var condition = new FluentConditionExpression();518        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)519        {520            var filter = new FluentFilterExpression();521522            definition(filter);523524            _linkEntity.LinkCriteria = filter.GetFilter();525526            return this;527        }528529        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)530        {531            var link = new FluentLinkEntity();532533            definition(link);534535            _linkEntity.LinkEntities.Add(link.GetLinkEntity());536537            return this;538        }539540        public IFluentLinkEntity LinkType(JoinOperator joinOperator)541        {542            _linkEntity.JoinOperator = joinOperator;543544            return this;545        }546547        public IFluentLinkEntity ToAttribute(string attributeName)548        {549            _linkEntity.LinkToAttributeName = attributeName;550551            return this;552        }553554        public IFluentLinkEntity ToEntity(string entityName)555        {556            _linkEntity.LinkToEntityName = entityName;557558            return this;559        }560561        internal LinkEntity GetLinkEntity()562        {563            return _linkEntity;564        }565    }566567    public interface IFluentFilterExpression568    {569        /**570        * <summary>571        * Use this for setting further options of your filter.572        * </summary>573        */574        IFluentFilterExpressionSetting With { get; }575576        /**577        * <summary>578        * Use this for adding a condition on an attribute to your filter.579        * </summary>580        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>581        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>582        */583        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);584585        /**586         * <summary>587         * Adds nested filter conditions to your filter.588         * </summary>589         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>590         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>591         */592        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);593    }  594 - 7595            definition(condition);596 - 7597            _filter.Conditions.Add(condition.GetCondition());598 - 7599            return this; - 7600        }601602        internal FilterExpression GetFilter() - 6603        { - 6604            return _filter; - 6605        }606    }607608    public interface IFluentConditionExpression609    {610        /**611         * <summary>612         * Set the entity name that your condition attribute targets, if it is not the main entity.613         * </summary>614         * <param name="entityName">Entity Logical Name</param>615         */616        IFluentConditionExpression Of(string entityName);617618        /**619         * <summary>620         * Set the logical name of the attribute that your condition targets.621         * </summary>622         * <param name="attributeName">Attribute logical name</param>623         */624        IFluentConditionExpression Named(string attributeName);595    public interface IFluentFilterExpressionSetting596    {597        /**598         * <summary>599         * Sets the logical operator for chaining multiple conditions in this filter.600         * </summary>601         */602        IFluentFilterExpression Operator(LogicalOperator filterOperator);603    }604605    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting606    {607        private FilterExpression _filter;608 + 10609        public FluentFilterExpression() + 10610        { + 10611            _filter = new FilterExpression(); + 10612        }613614        public IFluentFilterExpressionSetting With615        {616            get + 6617            { + 6618                return this; + 6619            }620        }621622        public IFluentFilterExpression Operator(LogicalOperator filterOperator) + 6623        { + 6624            _filter.FilterOperator = filterOperator;  625626        /**627         * <summary>628         * Set the condition operator for your condition.629         * </summary>630         * <param name="conditionOperator">Condition Operator Enum</param>631         */632        IFluentConditionExpression Is(ConditionOperator conditionOperator);633634        /**635         * <summary>636         * Sets the value for the condition.637         * </summary>638         * <param name="value">Single object, use object array overload if necessary.</param>639         */640        IFluentConditionExpression Value(object value);641642        /**643         * <summary>644         * Sets the values for the condition.645         * </summary>646         * <param name="value">Object array, use object overload if necessary.</param>647         */648        IFluentConditionExpression Value(params object[] value);649650        /**651         * <summary>652         * Alias for Value, provides better readability on Equal conditions.653         * Sets the value for the condition.654         * </summary>655         * <param name="value">Single object, use object array overload if necessary.</param>656         */657        IFluentConditionExpression To(object value);658 + 6626            return this; + 6627        }628629        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition) + 1630        { + 1631            var filter = new FluentFilterExpression();632 + 1633            definition(filter);634 + 1635            _filter.Filters.Add(filter.GetFilter());636 + 1637            return this; + 1638        }639640        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition) + 11641        { + 11642            var condition = new FluentConditionExpression();643 + 11644            definition(condition);645 + 11646            _filter.Conditions.Add(condition.GetCondition());647 + 11648            return this; + 11649        }650651        internal FilterExpression GetFilter() + 10652        { + 10653            return _filter; + 10654        }655    }656657    public interface IFluentConditionExpression658    {  659        /**  660         * <summary>661         * Alias for Value, provides better readability on Equal conditions.662         * Sets the values for the condition.663         * </summary>664         * <param name="value">Object array, use object overload if necessary.</param>665         */666        IFluentConditionExpression To(params object[] value);667    }668669    public class FluentConditionExpression : IFluentConditionExpression670    {671        private ConditionExpression _condition;672673        public FluentConditionExpression()674        {675            _condition = new ConditionExpression();676        }677678        public IFluentConditionExpression Is(ConditionOperator conditionOperator)679        {680            _condition.Operator = conditionOperator;681682            return this;683        }684685        public IFluentConditionExpression Named(string attributeName)686        {687            _condition.AttributeName = attributeName;688689            return this;690        }691692        public IFluentConditionExpression Of(string entityName)693        {694            _condition.EntityName = entityName;695696            return this;697        }661         * Set the entity name that your condition attribute targets, if it is not the main entity.662         * </summary>663         * <param name="entityName">Entity Logical Name</param>664         */665        IFluentConditionExpression Of(string entityName);666667        /**668         * <summary>669         * Set the logical name of the attribute that your condition targets.670         * </summary>671         * <param name="attributeName">Attribute logical name</param>672         */673        IFluentConditionExpression Named(string attributeName);674675        /**676         * <summary>677         * Set the condition operator for your condition.678         * </summary>679         * <param name="conditionOperator">Condition Operator Enum</param>680         */681        IFluentConditionExpression Is(ConditionOperator conditionOperator);682683        /**684         * <summary>685         * Sets the value for the condition.686         * </summary>687         * <param name="value">Single object, use object array overload if necessary.</param>688         */689        IFluentConditionExpression Value(object value);690691        /**692         * <summary>693         * Sets the values for the condition.694         * </summary>695         * <param name="value">Object array, use object overload if necessary.</param>696         */697        IFluentConditionExpression Value(params object[] value);  698699        public IFluentConditionExpression To(object value)700        {701            return Value(value);702        }703704        public IFluentConditionExpression To(params object[] value)705        {706            return Value(value);707        }708709        public IFluentConditionExpression Value(object value)710        {711            _condition.Values.Add(value);712713            return this;714        }715716        public IFluentConditionExpression Value(params object[] value)717        {718            _condition.Values.AddRange(value);719720            return this;721        }722723        internal ConditionExpression GetCondition ()724        {725            return _condition;726        }727    }728729    public interface IFluentOrderExpression730    {731        /**732         * <summary>733         * Set the attribute name to order by.734         * </summary>735         * <param name="attributeName">Attribute logical name</param>736         */737        IFluentOrderExpression By(string attributeName);738739        /**740         * <summary>741         * Sets the sort order to be ascending.742         * </summary>743         */744        IFluentOrderExpression Ascending();745746        /**747         * <summary>748         * Sets the sort order to be descending.749         * </summary>750         */751        IFluentOrderExpression Descending();752    }753754    public class FluentOrderExpression : IFluentOrderExpression755    {756        private OrderExpression _order;699        /**700         * <summary>701         * Alias for Value, provides better readability on Equal conditions.702         * Sets the value for the condition.703         * </summary>704         * <param name="value">Single object, use object array overload if necessary.</param>705         */706        IFluentConditionExpression To(object value);707708        /**709         * <summary>710         * Alias for Value, provides better readability on Equal conditions.711         * Sets the values for the condition.712         * </summary>713         * <param name="value">Object array, use object overload if necessary.</param>714         */715        IFluentConditionExpression To(params object[] value);716    }717718    public class FluentConditionExpression : IFluentConditionExpression719    {720        private ConditionExpression _condition;721722        public FluentConditionExpression()723        {724            _condition = new ConditionExpression();725        }726727        public IFluentConditionExpression Is(ConditionOperator conditionOperator)728        {729            _condition.Operator = conditionOperator;730731            return this;732        }733734        public IFluentConditionExpression Named(string attributeName)735        {736            _condition.AttributeName = attributeName;737738            return this;739        }740741        public IFluentConditionExpression Of(string entityName)742        {743            _condition.EntityName = entityName;744745            return this;746        }747748        public IFluentConditionExpression To(object value)749        {750            return Value(value);751        }752753        public IFluentConditionExpression To(params object[] value)754        {755            return Value(value);756        }  757758        public FluentOrderExpression ()758        public IFluentConditionExpression Value(object value)  759        {760            _order = new OrderExpression();761        }762763        public IFluentOrderExpression By(string attributeName)764        {765            _order.AttributeName = attributeName;766767            return this;768        }769770        public IFluentOrderExpression Ascending()771        {772            _order.OrderType = OrderType.Ascending;773774            return this;760            _condition.Values.Add(value);761762            return this;763        }764765        public IFluentConditionExpression Value(params object[] value)766        {767            _condition.Values.AddRange(value);768769            return this;770        }771772        internal ConditionExpression GetCondition ()773        {774            return _condition;  775        }776777        public IFluentOrderExpression Descending()778        {779            _order.OrderType = OrderType.Descending;780781            return this;782        }783784        internal OrderExpression GetOrder()785        {786            return _order;787        }788    }789790    public interface IFluentPagingInfo791    {792        /**793         * <summary>794         * Set the page number to retrieve. Is set to 1 by default.795         * </summary>796         * <param name="number">Number of the page, starts at 1.</param>797         */798        IFluentPagingInfo PageNumber(int number);799800        /**801         * <summary>802         * Set the paging cookie for retrieving records from pages after the first.803         * </summary>804         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>805         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>806         */807        IFluentPagingInfo PagingCookie(string pagingCookie);808809        /**810         * <summary>811         * Set the size of each page.812         * </summary>813         * <param name="number">Number of records to return per page.</param>814         */815        IFluentPagingInfo PageSize(int number);816817        /**818         * <summary>819         * Specifies whether the total record count of your query results should be retrieved.820         * </summary>821         * <param name="returnTotal">True for returning total record count, false otherwise.</param>822         */823        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);824    }776    }777778    public interface IFluentOrderExpression779    {780        /**781         * <summary>782         * Set the attribute name to order by.783         * </summary>784         * <param name="attributeName">Attribute logical name</param>785         */786        IFluentOrderExpression By(string attributeName);787788        /**789         * <summary>790         * Sets the sort order to be ascending.791         * </summary>792         */793        IFluentOrderExpression Ascending();794795        /**796         * <summary>797         * Sets the sort order to be descending.798         * </summary>799         */800        IFluentOrderExpression Descending();801    }802803    public class FluentOrderExpression : IFluentOrderExpression804    {805        private OrderExpression _order;806807        public FluentOrderExpression ()808        {809            _order = new OrderExpression();810        }811812        public IFluentOrderExpression By(string attributeName)813        {814            _order.AttributeName = attributeName;815816            return this;817        }818819        public IFluentOrderExpression Ascending()820        {821            _order.OrderType = OrderType.Ascending;822823            return this;824        }  825826    public class FluentPagingInfo : IFluentPagingInfo827    {828        private PagingInfo _pagingInfo;826        public IFluentOrderExpression Descending()827        {828            _order.OrderType = OrderType.Descending;  829830        public FluentPagingInfo()831        {832            _pagingInfo = new PagingInfo833            {834                PageNumber = 1835            };830            return this;831        }832833        internal OrderExpression GetOrder()834        {835            return _order;  836        }837838        public IFluentPagingInfo PageNumber(int number)839        {840            _pagingInfo.PageNumber = number;841842            return this;843        }844845        public IFluentPagingInfo PageSize(int number)846        {847            _pagingInfo.Count = number;837    }838839    public interface IFluentPagingInfo840    {841        /**842         * <summary>843         * Set the page number to retrieve. Is set to 1 by default.844         * </summary>845         * <param name="number">Number of the page, starts at 1.</param>846         */847        IFluentPagingInfo PageNumber(int number);  848849            return this;850        }851852        public IFluentPagingInfo PagingCookie(string pagingCookie)853        {854            _pagingInfo.PagingCookie = pagingCookie;855856            return this;857        }858859        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)860        {861            _pagingInfo.ReturnTotalRecordCount = returnTotal;862863            return this;864        }849        /**850         * <summary>851         * Set the paging cookie for retrieving records from pages after the first.852         * </summary>853         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>854         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>855         */856        IFluentPagingInfo PagingCookie(string pagingCookie);857858        /**859         * <summary>860         * Set the size of each page.861         * </summary>862         * <param name="number">Number of records to return per page.</param>863         */864        IFluentPagingInfo PageSize(int number);  865866        public PagingInfo GetPagingInfo()867        {868            return _pagingInfo;869        }870    }871}866        /**867         * <summary>868         * Specifies whether the total record count of your query results should be retrieved.869         * </summary>870         * <param name="returnTotal">True for returning total record count, false otherwise.</param>871         */872        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);873    }874875    public class FluentPagingInfo : IFluentPagingInfo876    {877        private PagingInfo _pagingInfo;878879        public FluentPagingInfo()880        {881            _pagingInfo = new PagingInfo882            {883                PageNumber = 1884            };885        }886887        public IFluentPagingInfo PageNumber(int number)888        {889            _pagingInfo.PageNumber = number;890891            return this;892        }893894        public IFluentPagingInfo PageSize(int number)895        {896            _pagingInfo.Count = number;897898            return this;899        }900901        public IFluentPagingInfo PagingCookie(string pagingCookie)902        {903            _pagingInfo.PagingCookie = pagingCookie;904905            return this;906        }907908        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)909        {910            _pagingInfo.ReturnTotalRecordCount = returnTotal;911912            return this;913        }914915        public PagingInfo GetPagingInfo()916        {917            return _pagingInfo;918        }919    }920} - + diff --git a/reports/Xrm.Oss.FluentQuery_FluentLinkEntity.htm b/reports/Xrm.Oss.FluentQuery_FluentLinkEntity.htm index f2d5285..a558f75 100644 --- a/reports/Xrm.Oss.FluentQuery_FluentLinkEntity.htm +++ b/reports/Xrm.Oss.FluentQuery_FluentLinkEntity.htm @@ -20,7 +20,7 @@

Summary

Covered lines:53 Uncovered lines:0 Coverable lines:53 -Total lines:871 +Total lines:920 Line coverage:100% @@ -132,809 +132,858 @@

 84  85        /**  86         * <summary>87         * Returns the Query Expression that represents the current fluent query.87         * Adds all columns to the query. This is disadvised, specify the columns you need if possible.  88         * </summary>  89         */90        QueryExpression Expression { get; }90        IFluentQuery<T> IncludeAllColumns();  91  92        /**  93         * <summary>94         * Retrieves the first page for your query.94         * Returns the Query Expression that represents the current fluent query.  95         * </summary>96         * <returns>Records retrieved from your query.</returns>97         */98        List<T> Retrieve();99100        /**101         * <summary>102         * Retrieves all pages for your query.103         * </summary>104         * <returns>Records retrieved from your query.</returns>105         */106        List<T> RetrieveAll();107108        /**109         * <summary>110         * Use this for setting further options in your query.111         * </summary>96         */97        QueryExpression Expression { get; }9899        /**100         * <summary>101         * Retrieves the first page for your query.102         * </summary>103         * <returns>Records retrieved from your query.</returns>104         */105        List<T> Retrieve();106107        /**108         * <summary>109         * Retrieves all pages for your query.110         * </summary>111         * <returns>Records retrieved from your query.</returns>  112         */113        IFluentQuerySetting<T> With { get; }113        List<T> RetrieveAll();  114  115        /**  116         * <summary>117         * Adds a link to a connected entity.117         * Use this for setting further options in your query.  118         * </summary>119         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>120         */121        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);122123        /**124         * <summary>125         * Adds filter conditions to your query.126         * </summary>127         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>128         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>129         */130        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);131132        /**133         * <summary>134         * Adds an order expression to your query.135         * </summary>136         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>137         */138        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);139    }140141    public interface IFluentQuerySetting<T> where T : Entity142    {143        /**144         * <summary>145         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.146         * </summary>147         * <param name="topCount">Top X count of records to retrieve</param>148         */149        IFluentQuery<T> RecordCount(int? topCount);150151        /**152         * <summary>153         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi154         * </summary>155         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 156         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>157         */158        IFluentQuery<T> DatabaseLock(bool useLock = true);159160        /**161         * <summary>162         * Specifies whether duplicate records in your query will be filtered out or not.163         * </summary>164         * <param name="unique">True for only returning unique records, false otherwise</param>165         */166        IFluentQuery<T> UniqueRecords(bool unique = true);167168        /**169         * <summary>170         * Adds paging info to your query, such as page size, page number or paging cookie.171         * </summary>172         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>173         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>174         */175        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);176177        /**178         * <summary>179         * Specifies whether the total record count of your query results should be retrieved.180         * </summary>181         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>182         */183        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);184    }185186    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity187    {188        private QueryExpression _query;189        private IOrganizationService _service;119         */120        IFluentQuerySetting<T> With { get; }121122        /**123         * <summary>124         * Adds a link to a connected entity.125         * </summary>126         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>127         */128        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);129130        /**131         * <summary>132         * Adds filter conditions to your query.133         * </summary>134         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>135         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>136         */137        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);138139        /**140         * <summary>141         * Adds another condition to the top level filter expression.142         * </summary>143         * <param name="definition">The condition expression to add.</param>144         */145        void AddCondition(Action<IFluentConditionExpression> definition);146147        /**148         * <summary>149         * Adds a child filter to your top level filter.150         * </summary>151         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>152         */153        void AddFilter(Action<IFluentFilterExpression> definition);154155        /**156         * <summary>157         * Adds an order expression to your query.158         * </summary>159         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>160         */161        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);162    }163164    public interface IFluentQuerySetting<T> where T : Entity165    {166        /**167         * <summary>168         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.169         * </summary>170         * <param name="topCount">Top X count of records to retrieve</param>171         */172        IFluentQuery<T> RecordCount(int? topCount);173174        /**175         * <summary>176         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi177         * </summary>178         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 179         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>180         */181        IFluentQuery<T> DatabaseLock(bool useLock = true);182183        /**184         * <summary>185         * Specifies whether duplicate records in your query will be filtered out or not.186         * </summary>187         * <param name="unique">True for only returning unique records, false otherwise</param>188         */189        IFluentQuery<T> UniqueRecords(bool unique = true);  190191        public FluentQuery(string entityName, IOrganizationService service)192        {193            _query = new QueryExpression194            {195                EntityName = entityName,196                NoLock = true197            };198199            _service = service;200        }201202        public IFluentQuery<T> IncludeColumns(params string[] columns)203        {204            _query.ColumnSet.AddColumns(columns);205206            return this;207        }191        /**192         * <summary>193         * Adds paging info to your query, such as page size, page number or paging cookie.194         * </summary>195         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>196         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>197         */198        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);199200        /**201         * <summary>202         * Specifies whether the total record count of your query results should be retrieved.203         * </summary>204         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>205         */206        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);207    }  208209        public IFluentQuerySetting<T> With210        {211            get212            {213                return this;214            }215        }216217        public IFluentQuery<T> RecordCount(int? topCount)218        {219            _query.TopCount = topCount;220221            return this;222        }223224        public IFluentQuery<T> DatabaseLock(bool useLock = true)225        {226            _query.NoLock = !useLock;227228            return this;229        }230231        public List<T> Retrieve()232        {233            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())234                .ToList();235        }209    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity210    {211        private QueryExpression _query;212        private IOrganizationService _service;213214        public FluentQuery(string entityName, IOrganizationService service)215        {216            _query = new QueryExpression217            {218                EntityName = entityName,219                NoLock = true220            };221222            _service = service;223        }224225        public IFluentQuery<T> IncludeColumns(params string[] columns)226        {227            _query.ColumnSet.AllColumns = false;228            _query.ColumnSet.AddColumns(columns);229230            return this;231        }232233        public IFluentQuery<T> IncludeAllColumns()234        {235            _query.ColumnSet.AllColumns = true;  236237        public List<T> RetrieveAll()238        {239            var records = new List<T>();240241            var previousPageNumber = _query.PageInfo.PageNumber;242            var previousPagingCookie = _query.PageInfo.PagingCookie;243244            var moreRecords = false;245            var pageNumber = previousPageNumber;246            string pagingCookie = previousPagingCookie;237            return this;238        }239240        public IFluentQuerySetting<T> With241        {242            get243            {244                return this;245            }246        }  247248            do249            {250                _query.PageInfo.PageNumber = pageNumber;251                _query.PageInfo.PagingCookie = pagingCookie;252253                var response = _service.RetrieveMultiple(_query);254                var result = response.Entities.Select(e => e.ToEntity<T>())255                    .ToList();256257                records.AddRange(result);248        public IFluentQuery<T> RecordCount(int? topCount)249        {250            _query.TopCount = topCount;251252            return this;253        }254255        public IFluentQuery<T> DatabaseLock(bool useLock = true)256        {257            _query.NoLock = !useLock;  258259                moreRecords = response.MoreRecords;260                pageNumber++;261            }262            while (moreRecords);263264            _query.PageInfo.PageNumber = previousPageNumber;265            _query.PageInfo.PagingCookie = previousPagingCookie;266267            return records;268        }269270        public IFluentQuery<T> UniqueRecords(bool unique = true)271        {272            _query.Distinct = true;273274            return this;275        }276277        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)278        {279            var link = new FluentLinkEntity();280281            definition(link);282283            _query.LinkEntities.Add(link.GetLinkEntity());284285            return this;286        }259            return this;260        }261262        public List<T> Retrieve()263        {264            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())265                .ToList();266        }267268        public List<T> RetrieveAll()269        {270            var records = new List<T>();271272            var previousPageNumber = _query.PageInfo.PageNumber;273            var previousPagingCookie = _query.PageInfo.PagingCookie;274275            var moreRecords = false;276            var pageNumber = previousPageNumber;277            string pagingCookie = previousPagingCookie;278279            do280            {281                _query.PageInfo.PageNumber = pageNumber;282                _query.PageInfo.PagingCookie = pagingCookie;283284                var response = _service.RetrieveMultiple(_query);285                var result = response.Entities.Select(e => e.ToEntity<T>())286                    .ToList();  287288        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)289        {290            var filter = new FluentFilterExpression();291292            definition(filter);293294            _query.Criteria = filter.GetFilter();295296            return this;297        }298299        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)300        {301            var order = new FluentOrderExpression();302303            definition(order);288                records.AddRange(result);289290                moreRecords = response.MoreRecords;291                pageNumber++;292            }293            while (moreRecords);294295            _query.PageInfo.PageNumber = previousPageNumber;296            _query.PageInfo.PagingCookie = previousPagingCookie;297298            return records;299        }300301        public IFluentQuery<T> UniqueRecords(bool unique = true)302        {303            _query.Distinct = true;  304305            _query.Orders.Add(order.GetOrder());306307            return this;308        }309310        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)311        {312            var PagingInfo = new FluentPagingInfo();305            return this;306        }307308        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)309        {310            var link = new FluentLinkEntity();311312            definition(link);  313314            definition(PagingInfo);314            _query.LinkEntities.Add(link.GetLinkEntity());  315316            _query.PageInfo = PagingInfo.GetPagingInfo();317318            return this;319        }320321        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)322        {323            _query.PageInfo.ReturnTotalRecordCount = true;316            return this;317        }318319        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)320        {321            var filter = new FluentFilterExpression();322323            definition(filter);  324325            return this;326        }327328        public QueryExpression Expression329        {330            get331            {332                return _query;333            }334        }335    }336337    public interface IFluentLinkEntity338    {339        /**340         * <summary>341         * Logical name of entity that the link is created from.342         * </summary>343         * <param name="entityName">Entity Logical Name</param>344         */345        IFluentLinkEntity FromEntity(string entityName);346347        /**348         * <summary>349         * Logical name of attribute that the link is created from.350         * </summary>351         * <param name="attributeName">Attribute Logical Name</param>352         */353        IFluentLinkEntity FromAttribute(string attributeName);354355        /**356         * <summary>357         * Logical name of entity that the link is created to.358         * </summary>359         * <param name="entityName">Entity Logical Name</param>360         */361        IFluentLinkEntity ToEntity(string entityName);325            _query.Criteria = filter.GetFilter();326327            return this;328        }329330        public void AddCondition(Action<IFluentConditionExpression> definition)331        {332            var condition = new FluentConditionExpression();333334            definition(condition);335336            _query.Criteria.AddCondition(condition.GetCondition());337        }338339        public void AddFilter(Action<IFluentFilterExpression> definition)340        {341            var filter = new FluentFilterExpression();342343            definition(filter);344345            _query.Criteria.AddFilter(filter.GetFilter());346        }347348        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)349        {350            var order = new FluentOrderExpression();351352            definition(order);353354            _query.Orders.Add(order.GetOrder());355356            return this;357        }358359        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)360        {361            var PagingInfo = new FluentPagingInfo();  362363        /**364         * <summary>365         * Logical name of attribute that the link is created to.366         * </summary>367         * <param name="attributeName">Attribute Logical Name</param>368         */369        IFluentLinkEntity ToAttribute(string attributeName);370371        /**372         * <summary>373         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.374         * </summary>375         * <param name="columns">Params array of your columns.</param>376         */377        IFluentLinkEntity IncludeColumns(params string[] columns);378379        /**380        * <summary>381        * Use this for setting further options of your link.382        * </summary>383        */384        IFluentLinkEntitySetting With { get; }363            definition(PagingInfo);364365            _query.PageInfo = PagingInfo.GetPagingInfo();366367            return this;368        }369370        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)371        {372            _query.PageInfo.ReturnTotalRecordCount = true;373374            return this;375        }376377        public QueryExpression Expression378        {379            get380            {381                return _query;382            }383        }384    }  385386        /**387         * <summary>388         * Adds a nested link to this link.389         * </summary>390         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>391         */392        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);393394        /**395         * <summary>396         * Adds filter conditions to your link.397         * </summary>398         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>399         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>400         */401        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);402    }386    public interface IFluentLinkEntity387    {388        /**389         * <summary>390         * Logical name of entity that the link is created from.391         * </summary>392         * <param name="entityName">Entity Logical Name</param>393         */394        IFluentLinkEntity FromEntity(string entityName);395396        /**397         * <summary>398         * Logical name of attribute that the link is created from.399         * </summary>400         * <param name="attributeName">Attribute Logical Name</param>401         */402        IFluentLinkEntity FromAttribute(string attributeName);  403404    public interface IFluentLinkEntitySetting405    {406        /**407         * <summary>408         * Sets an alias for the results of this link entity.409         * </summary>410         * <param name="name">Alias to set in results.</param>411         */412        IFluentLinkEntity Alias(string name);413414        /**415         * <summary>Join type of this link.</summary>416         * <param name="joinOperator">Join type to use.</param>404        /**405         * <summary>406         * Logical name of entity that the link is created to.407         * </summary>408         * <param name="entityName">Entity Logical Name</param>409         */410        IFluentLinkEntity ToEntity(string entityName);411412        /**413         * <summary>414         * Logical name of attribute that the link is created to.415         * </summary>416         * <param name="attributeName">Attribute Logical Name</param>  417         */418        IFluentLinkEntity LinkType(JoinOperator joinOperator);419    }420421    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting422    {423        private LinkEntity _linkEntity;424 - 7425        public FluentLinkEntity() - 7426        { - 7427            _linkEntity = new LinkEntity - 7428            { - 7429                Columns = new ColumnSet() - 7430            }; - 7431        }432433        public IFluentLinkEntitySetting With434        {435            get - 6436            { - 6437                return this; - 6438            }439        }440441        public IFluentLinkEntity Alias(string name) - 4442        { - 4443            _linkEntity.EntityAlias = name;444 - 4445            return this; - 4446        }447448        public IFluentLinkEntity FromAttribute(string attributeName) - 5449        { - 5450            _linkEntity.LinkFromAttributeName = attributeName;451 - 5452            return this; - 5453        }454455        public IFluentLinkEntity FromEntity(string entityName) - 5456        { - 5457            _linkEntity.LinkFromEntityName = entityName;458 - 5459            return this; - 5460        }461462        public IFluentLinkEntity IncludeColumns(params string[] columns) - 1463        { - 1464            _linkEntity.Columns.AddColumns(columns);465 - 1466            return this; - 1467        }468469        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition) - 1470        { - 1471            var filter = new FluentFilterExpression();472 - 1473            definition(filter);474 - 1475            _linkEntity.LinkCriteria = filter.GetFilter();476 - 1477            return this; - 1478        }479480        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition) - 1481        { - 1482            var link = new FluentLinkEntity();483 - 1484            definition(link);485 - 1486            _linkEntity.LinkEntities.Add(link.GetLinkEntity());487 - 1488            return this; - 1489        }490491        public IFluentLinkEntity LinkType(JoinOperator joinOperator) - 2492        { - 2493            _linkEntity.JoinOperator = joinOperator;494 - 2495            return this; - 2496        }497498        public IFluentLinkEntity ToAttribute(string attributeName) - 5499        { - 5500            _linkEntity.LinkToAttributeName = attributeName;501 - 5502            return this; - 5503        }504505        public IFluentLinkEntity ToEntity(string entityName) - 5506        { - 5507            _linkEntity.LinkToEntityName = entityName;508 - 5509            return this; - 5510        }511512        internal LinkEntity GetLinkEntity() - 7513        { - 7514            return _linkEntity; - 7515        }516    }418        IFluentLinkEntity ToAttribute(string attributeName);419420        /**421         * <summary>422         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.423         * </summary>424         * <param name="columns">Params array of your columns.</param>425         */426        IFluentLinkEntity IncludeColumns(params string[] columns);427428        /**429        * <summary>430        * Use this for setting further options of your link.431        * </summary>432        */433        IFluentLinkEntitySetting With { get; }434435        /**436         * <summary>437         * Adds a nested link to this link.438         * </summary>439         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>440         */441        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);442443        /**444         * <summary>445         * Adds filter conditions to your link.446         * </summary>447         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>448         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>449         */450        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);451    }452453    public interface IFluentLinkEntitySetting454    {455        /**456         * <summary>457         * Sets an alias for the results of this link entity.458         * </summary>459         * <param name="name">Alias to set in results.</param>460         */461        IFluentLinkEntity Alias(string name);462463        /**464         * <summary>Join type of this link.</summary>465         * <param name="joinOperator">Join type to use.</param>466         */467        IFluentLinkEntity LinkType(JoinOperator joinOperator);468    }469470    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting471    {472        private LinkEntity _linkEntity;473 + 7474        public FluentLinkEntity() + 7475        { + 7476            _linkEntity = new LinkEntity + 7477            { + 7478                Columns = new ColumnSet() + 7479            }; + 7480        }481482        public IFluentLinkEntitySetting With483        {484            get + 6485            { + 6486                return this; + 6487            }488        }489490        public IFluentLinkEntity Alias(string name) + 4491        { + 4492            _linkEntity.EntityAlias = name;493 + 4494            return this; + 4495        }496497        public IFluentLinkEntity FromAttribute(string attributeName) + 5498        { + 5499            _linkEntity.LinkFromAttributeName = attributeName;500 + 5501            return this; + 5502        }503504        public IFluentLinkEntity FromEntity(string entityName) + 5505        { + 5506            _linkEntity.LinkFromEntityName = entityName;507 + 5508            return this; + 5509        }510511        public IFluentLinkEntity IncludeColumns(params string[] columns) + 1512        { + 1513            _linkEntity.Columns.AddColumns(columns);514 + 1515            return this; + 1516        }  517518    public interface IFluentFilterExpression519    {520        /**521        * <summary>522        * Use this for setting further options of your filter.523        * </summary>524        */525        IFluentFilterExpressionSetting With { get; }526527        /**528        * <summary>529        * Use this for adding a condition on an attribute to your filter.530        * </summary>531        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>532        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>533        */534        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);535536        /**537         * <summary>538         * Adds nested filter conditions to your filter.539         * </summary>540         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>541         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>542         */543        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);544    }545546    public interface IFluentFilterExpressionSetting547    {548        /**549         * <summary>550         * Sets the logical operator for chaining multiple conditions in this filter.551         * </summary>552         */553        IFluentFilterExpression Operator(LogicalOperator filterOperator);554    }555556    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting557    {558        private FilterExpression _filter;559560        public FluentFilterExpression()561        {562            _filter = new FilterExpression();563        }564565        public IFluentFilterExpressionSetting With566        {567            get568            {569                return this;570            }571        }572573        public IFluentFilterExpression Operator(LogicalOperator filterOperator)574        {575            _filter.FilterOperator = filterOperator;576577            return this;578        }579580        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)581        {582            var filter = new FluentFilterExpression();583584            definition(filter);585586            _filter.Filters.Add(filter.GetFilter());587588            return this;589        }590591        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)592        {593            var condition = new FluentConditionExpression();518        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition) + 1519        { + 1520            var filter = new FluentFilterExpression();521 + 1522            definition(filter);523 + 1524            _linkEntity.LinkCriteria = filter.GetFilter();525 + 1526            return this; + 1527        }528529        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition) + 1530        { + 1531            var link = new FluentLinkEntity();532 + 1533            definition(link);534 + 1535            _linkEntity.LinkEntities.Add(link.GetLinkEntity());536 + 1537            return this; + 1538        }539540        public IFluentLinkEntity LinkType(JoinOperator joinOperator) + 2541        { + 2542            _linkEntity.JoinOperator = joinOperator;543 + 2544            return this; + 2545        }546547        public IFluentLinkEntity ToAttribute(string attributeName) + 5548        { + 5549            _linkEntity.LinkToAttributeName = attributeName;550 + 5551            return this; + 5552        }553554        public IFluentLinkEntity ToEntity(string entityName) + 5555        { + 5556            _linkEntity.LinkToEntityName = entityName;557 + 5558            return this; + 5559        }560561        internal LinkEntity GetLinkEntity() + 7562        { + 7563            return _linkEntity; + 7564        }565    }566567    public interface IFluentFilterExpression568    {569        /**570        * <summary>571        * Use this for setting further options of your filter.572        * </summary>573        */574        IFluentFilterExpressionSetting With { get; }575576        /**577        * <summary>578        * Use this for adding a condition on an attribute to your filter.579        * </summary>580        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>581        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>582        */583        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);584585        /**586         * <summary>587         * Adds nested filter conditions to your filter.588         * </summary>589         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>590         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>591         */592        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);593    }  594595            definition(condition);596597            _filter.Conditions.Add(condition.GetCondition());598599            return this;600        }601602        internal FilterExpression GetFilter()603        {604            return _filter;605        }606    }607608    public interface IFluentConditionExpression609    {610        /**611         * <summary>612         * Set the entity name that your condition attribute targets, if it is not the main entity.613         * </summary>614         * <param name="entityName">Entity Logical Name</param>615         */616        IFluentConditionExpression Of(string entityName);617618        /**619         * <summary>620         * Set the logical name of the attribute that your condition targets.621         * </summary>622         * <param name="attributeName">Attribute logical name</param>623         */624        IFluentConditionExpression Named(string attributeName);595    public interface IFluentFilterExpressionSetting596    {597        /**598         * <summary>599         * Sets the logical operator for chaining multiple conditions in this filter.600         * </summary>601         */602        IFluentFilterExpression Operator(LogicalOperator filterOperator);603    }604605    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting606    {607        private FilterExpression _filter;608609        public FluentFilterExpression()610        {611            _filter = new FilterExpression();612        }613614        public IFluentFilterExpressionSetting With615        {616            get617            {618                return this;619            }620        }621622        public IFluentFilterExpression Operator(LogicalOperator filterOperator)623        {624            _filter.FilterOperator = filterOperator;  625626        /**627         * <summary>628         * Set the condition operator for your condition.629         * </summary>630         * <param name="conditionOperator">Condition Operator Enum</param>631         */632        IFluentConditionExpression Is(ConditionOperator conditionOperator);633634        /**635         * <summary>636         * Sets the value for the condition.637         * </summary>638         * <param name="value">Single object, use object array overload if necessary.</param>639         */640        IFluentConditionExpression Value(object value);641642        /**643         * <summary>644         * Sets the values for the condition.645         * </summary>646         * <param name="value">Object array, use object overload if necessary.</param>647         */648        IFluentConditionExpression Value(params object[] value);649650        /**651         * <summary>652         * Alias for Value, provides better readability on Equal conditions.653         * Sets the value for the condition.654         * </summary>655         * <param name="value">Single object, use object array overload if necessary.</param>656         */657        IFluentConditionExpression To(object value);658626            return this;627        }628629        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)630        {631            var filter = new FluentFilterExpression();632633            definition(filter);634635            _filter.Filters.Add(filter.GetFilter());636637            return this;638        }639640        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)641        {642            var condition = new FluentConditionExpression();643644            definition(condition);645646            _filter.Conditions.Add(condition.GetCondition());647648            return this;649        }650651        internal FilterExpression GetFilter()652        {653            return _filter;654        }655    }656657    public interface IFluentConditionExpression658    {  659        /**  660         * <summary>661         * Alias for Value, provides better readability on Equal conditions.662         * Sets the values for the condition.663         * </summary>664         * <param name="value">Object array, use object overload if necessary.</param>665         */666        IFluentConditionExpression To(params object[] value);667    }668669    public class FluentConditionExpression : IFluentConditionExpression670    {671        private ConditionExpression _condition;672673        public FluentConditionExpression()674        {675            _condition = new ConditionExpression();676        }677678        public IFluentConditionExpression Is(ConditionOperator conditionOperator)679        {680            _condition.Operator = conditionOperator;681682            return this;683        }684685        public IFluentConditionExpression Named(string attributeName)686        {687            _condition.AttributeName = attributeName;688689            return this;690        }691692        public IFluentConditionExpression Of(string entityName)693        {694            _condition.EntityName = entityName;695696            return this;697        }661         * Set the entity name that your condition attribute targets, if it is not the main entity.662         * </summary>663         * <param name="entityName">Entity Logical Name</param>664         */665        IFluentConditionExpression Of(string entityName);666667        /**668         * <summary>669         * Set the logical name of the attribute that your condition targets.670         * </summary>671         * <param name="attributeName">Attribute logical name</param>672         */673        IFluentConditionExpression Named(string attributeName);674675        /**676         * <summary>677         * Set the condition operator for your condition.678         * </summary>679         * <param name="conditionOperator">Condition Operator Enum</param>680         */681        IFluentConditionExpression Is(ConditionOperator conditionOperator);682683        /**684         * <summary>685         * Sets the value for the condition.686         * </summary>687         * <param name="value">Single object, use object array overload if necessary.</param>688         */689        IFluentConditionExpression Value(object value);690691        /**692         * <summary>693         * Sets the values for the condition.694         * </summary>695         * <param name="value">Object array, use object overload if necessary.</param>696         */697        IFluentConditionExpression Value(params object[] value);  698699        public IFluentConditionExpression To(object value)700        {701            return Value(value);702        }703704        public IFluentConditionExpression To(params object[] value)705        {706            return Value(value);707        }708709        public IFluentConditionExpression Value(object value)710        {711            _condition.Values.Add(value);712713            return this;714        }715716        public IFluentConditionExpression Value(params object[] value)717        {718            _condition.Values.AddRange(value);719720            return this;721        }722723        internal ConditionExpression GetCondition ()724        {725            return _condition;726        }727    }728729    public interface IFluentOrderExpression730    {731        /**732         * <summary>733         * Set the attribute name to order by.734         * </summary>735         * <param name="attributeName">Attribute logical name</param>736         */737        IFluentOrderExpression By(string attributeName);738739        /**740         * <summary>741         * Sets the sort order to be ascending.742         * </summary>743         */744        IFluentOrderExpression Ascending();745746        /**747         * <summary>748         * Sets the sort order to be descending.749         * </summary>750         */751        IFluentOrderExpression Descending();752    }753754    public class FluentOrderExpression : IFluentOrderExpression755    {756        private OrderExpression _order;699        /**700         * <summary>701         * Alias for Value, provides better readability on Equal conditions.702         * Sets the value for the condition.703         * </summary>704         * <param name="value">Single object, use object array overload if necessary.</param>705         */706        IFluentConditionExpression To(object value);707708        /**709         * <summary>710         * Alias for Value, provides better readability on Equal conditions.711         * Sets the values for the condition.712         * </summary>713         * <param name="value">Object array, use object overload if necessary.</param>714         */715        IFluentConditionExpression To(params object[] value);716    }717718    public class FluentConditionExpression : IFluentConditionExpression719    {720        private ConditionExpression _condition;721722        public FluentConditionExpression()723        {724            _condition = new ConditionExpression();725        }726727        public IFluentConditionExpression Is(ConditionOperator conditionOperator)728        {729            _condition.Operator = conditionOperator;730731            return this;732        }733734        public IFluentConditionExpression Named(string attributeName)735        {736            _condition.AttributeName = attributeName;737738            return this;739        }740741        public IFluentConditionExpression Of(string entityName)742        {743            _condition.EntityName = entityName;744745            return this;746        }747748        public IFluentConditionExpression To(object value)749        {750            return Value(value);751        }752753        public IFluentConditionExpression To(params object[] value)754        {755            return Value(value);756        }  757758        public FluentOrderExpression ()758        public IFluentConditionExpression Value(object value)  759        {760            _order = new OrderExpression();761        }762763        public IFluentOrderExpression By(string attributeName)764        {765            _order.AttributeName = attributeName;766767            return this;768        }769770        public IFluentOrderExpression Ascending()771        {772            _order.OrderType = OrderType.Ascending;773774            return this;760            _condition.Values.Add(value);761762            return this;763        }764765        public IFluentConditionExpression Value(params object[] value)766        {767            _condition.Values.AddRange(value);768769            return this;770        }771772        internal ConditionExpression GetCondition ()773        {774            return _condition;  775        }776777        public IFluentOrderExpression Descending()778        {779            _order.OrderType = OrderType.Descending;780781            return this;782        }783784        internal OrderExpression GetOrder()785        {786            return _order;787        }788    }789790    public interface IFluentPagingInfo791    {792        /**793         * <summary>794         * Set the page number to retrieve. Is set to 1 by default.795         * </summary>796         * <param name="number">Number of the page, starts at 1.</param>797         */798        IFluentPagingInfo PageNumber(int number);799800        /**801         * <summary>802         * Set the paging cookie for retrieving records from pages after the first.803         * </summary>804         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>805         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>806         */807        IFluentPagingInfo PagingCookie(string pagingCookie);808809        /**810         * <summary>811         * Set the size of each page.812         * </summary>813         * <param name="number">Number of records to return per page.</param>814         */815        IFluentPagingInfo PageSize(int number);816817        /**818         * <summary>819         * Specifies whether the total record count of your query results should be retrieved.820         * </summary>821         * <param name="returnTotal">True for returning total record count, false otherwise.</param>822         */823        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);824    }776    }777778    public interface IFluentOrderExpression779    {780        /**781         * <summary>782         * Set the attribute name to order by.783         * </summary>784         * <param name="attributeName">Attribute logical name</param>785         */786        IFluentOrderExpression By(string attributeName);787788        /**789         * <summary>790         * Sets the sort order to be ascending.791         * </summary>792         */793        IFluentOrderExpression Ascending();794795        /**796         * <summary>797         * Sets the sort order to be descending.798         * </summary>799         */800        IFluentOrderExpression Descending();801    }802803    public class FluentOrderExpression : IFluentOrderExpression804    {805        private OrderExpression _order;806807        public FluentOrderExpression ()808        {809            _order = new OrderExpression();810        }811812        public IFluentOrderExpression By(string attributeName)813        {814            _order.AttributeName = attributeName;815816            return this;817        }818819        public IFluentOrderExpression Ascending()820        {821            _order.OrderType = OrderType.Ascending;822823            return this;824        }  825826    public class FluentPagingInfo : IFluentPagingInfo827    {828        private PagingInfo _pagingInfo;826        public IFluentOrderExpression Descending()827        {828            _order.OrderType = OrderType.Descending;  829830        public FluentPagingInfo()831        {832            _pagingInfo = new PagingInfo833            {834                PageNumber = 1835            };830            return this;831        }832833        internal OrderExpression GetOrder()834        {835            return _order;  836        }837838        public IFluentPagingInfo PageNumber(int number)839        {840            _pagingInfo.PageNumber = number;841842            return this;843        }844845        public IFluentPagingInfo PageSize(int number)846        {847            _pagingInfo.Count = number;837    }838839    public interface IFluentPagingInfo840    {841        /**842         * <summary>843         * Set the page number to retrieve. Is set to 1 by default.844         * </summary>845         * <param name="number">Number of the page, starts at 1.</param>846         */847        IFluentPagingInfo PageNumber(int number);  848849            return this;850        }851852        public IFluentPagingInfo PagingCookie(string pagingCookie)853        {854            _pagingInfo.PagingCookie = pagingCookie;855856            return this;857        }858859        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)860        {861            _pagingInfo.ReturnTotalRecordCount = returnTotal;862863            return this;864        }849        /**850         * <summary>851         * Set the paging cookie for retrieving records from pages after the first.852         * </summary>853         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>854         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>855         */856        IFluentPagingInfo PagingCookie(string pagingCookie);857858        /**859         * <summary>860         * Set the size of each page.861         * </summary>862         * <param name="number">Number of records to return per page.</param>863         */864        IFluentPagingInfo PageSize(int number);  865866        public PagingInfo GetPagingInfo()867        {868            return _pagingInfo;869        }870    }871}866        /**867         * <summary>868         * Specifies whether the total record count of your query results should be retrieved.869         * </summary>870         * <param name="returnTotal">True for returning total record count, false otherwise.</param>871         */872        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);873    }874875    public class FluentPagingInfo : IFluentPagingInfo876    {877        private PagingInfo _pagingInfo;878879        public FluentPagingInfo()880        {881            _pagingInfo = new PagingInfo882            {883                PageNumber = 1884            };885        }886887        public IFluentPagingInfo PageNumber(int number)888        {889            _pagingInfo.PageNumber = number;890891            return this;892        }893894        public IFluentPagingInfo PageSize(int number)895        {896            _pagingInfo.Count = number;897898            return this;899        }900901        public IFluentPagingInfo PagingCookie(string pagingCookie)902        {903            _pagingInfo.PagingCookie = pagingCookie;904905            return this;906        }907908        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)909        {910            _pagingInfo.ReturnTotalRecordCount = returnTotal;911912            return this;913        }914915        public PagingInfo GetPagingInfo()916        {917            return _pagingInfo;918        }919    }920} - + diff --git a/reports/Xrm.Oss.FluentQuery_FluentOrderExpression.htm b/reports/Xrm.Oss.FluentQuery_FluentOrderExpression.htm index f23868d..8460145 100644 --- a/reports/Xrm.Oss.FluentQuery_FluentOrderExpression.htm +++ b/reports/Xrm.Oss.FluentQuery_FluentOrderExpression.htm @@ -20,7 +20,7 @@

Summary

Covered lines:19 Uncovered lines:0 Coverable lines:19 -Total lines:871 +Total lines:920 Line coverage:100% @@ -126,802 +126,851 @@

 84  85        /**  86         * <summary>87         * Returns the Query Expression that represents the current fluent query.87         * Adds all columns to the query. This is disadvised, specify the columns you need if possible.  88         * </summary>  89         */90        QueryExpression Expression { get; }90        IFluentQuery<T> IncludeAllColumns();  91  92        /**  93         * <summary>94         * Retrieves the first page for your query.94         * Returns the Query Expression that represents the current fluent query.  95         * </summary>96         * <returns>Records retrieved from your query.</returns>97         */98        List<T> Retrieve();99100        /**101         * <summary>102         * Retrieves all pages for your query.103         * </summary>104         * <returns>Records retrieved from your query.</returns>105         */106        List<T> RetrieveAll();107108        /**109         * <summary>110         * Use this for setting further options in your query.111         * </summary>96         */97        QueryExpression Expression { get; }9899        /**100         * <summary>101         * Retrieves the first page for your query.102         * </summary>103         * <returns>Records retrieved from your query.</returns>104         */105        List<T> Retrieve();106107        /**108         * <summary>109         * Retrieves all pages for your query.110         * </summary>111         * <returns>Records retrieved from your query.</returns>  112         */113        IFluentQuerySetting<T> With { get; }113        List<T> RetrieveAll();  114  115        /**  116         * <summary>117         * Adds a link to a connected entity.117         * Use this for setting further options in your query.  118         * </summary>119         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>120         */121        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);122123        /**124         * <summary>125         * Adds filter conditions to your query.126         * </summary>127         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>128         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>129         */130        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);131132        /**133         * <summary>134         * Adds an order expression to your query.135         * </summary>136         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>137         */138        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);139    }140141    public interface IFluentQuerySetting<T> where T : Entity142    {143        /**144         * <summary>145         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.146         * </summary>147         * <param name="topCount">Top X count of records to retrieve</param>148         */149        IFluentQuery<T> RecordCount(int? topCount);150151        /**152         * <summary>153         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi154         * </summary>155         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 156         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>157         */158        IFluentQuery<T> DatabaseLock(bool useLock = true);159160        /**161         * <summary>162         * Specifies whether duplicate records in your query will be filtered out or not.163         * </summary>164         * <param name="unique">True for only returning unique records, false otherwise</param>165         */166        IFluentQuery<T> UniqueRecords(bool unique = true);167168        /**169         * <summary>170         * Adds paging info to your query, such as page size, page number or paging cookie.171         * </summary>172         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>173         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>174         */175        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);176177        /**178         * <summary>179         * Specifies whether the total record count of your query results should be retrieved.180         * </summary>181         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>182         */183        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);184    }185186    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity187    {188        private QueryExpression _query;189        private IOrganizationService _service;119         */120        IFluentQuerySetting<T> With { get; }121122        /**123         * <summary>124         * Adds a link to a connected entity.125         * </summary>126         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>127         */128        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);129130        /**131         * <summary>132         * Adds filter conditions to your query.133         * </summary>134         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>135         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>136         */137        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);138139        /**140         * <summary>141         * Adds another condition to the top level filter expression.142         * </summary>143         * <param name="definition">The condition expression to add.</param>144         */145        void AddCondition(Action<IFluentConditionExpression> definition);146147        /**148         * <summary>149         * Adds a child filter to your top level filter.150         * </summary>151         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>152         */153        void AddFilter(Action<IFluentFilterExpression> definition);154155        /**156         * <summary>157         * Adds an order expression to your query.158         * </summary>159         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>160         */161        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);162    }163164    public interface IFluentQuerySetting<T> where T : Entity165    {166        /**167         * <summary>168         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.169         * </summary>170         * <param name="topCount">Top X count of records to retrieve</param>171         */172        IFluentQuery<T> RecordCount(int? topCount);173174        /**175         * <summary>176         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi177         * </summary>178         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 179         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>180         */181        IFluentQuery<T> DatabaseLock(bool useLock = true);182183        /**184         * <summary>185         * Specifies whether duplicate records in your query will be filtered out or not.186         * </summary>187         * <param name="unique">True for only returning unique records, false otherwise</param>188         */189        IFluentQuery<T> UniqueRecords(bool unique = true);  190191        public FluentQuery(string entityName, IOrganizationService service)192        {193            _query = new QueryExpression194            {195                EntityName = entityName,196                NoLock = true197            };198199            _service = service;200        }201202        public IFluentQuery<T> IncludeColumns(params string[] columns)203        {204            _query.ColumnSet.AddColumns(columns);205206            return this;207        }191        /**192         * <summary>193         * Adds paging info to your query, such as page size, page number or paging cookie.194         * </summary>195         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>196         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>197         */198        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);199200        /**201         * <summary>202         * Specifies whether the total record count of your query results should be retrieved.203         * </summary>204         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>205         */206        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);207    }  208209        public IFluentQuerySetting<T> With210        {211            get212            {213                return this;214            }215        }216217        public IFluentQuery<T> RecordCount(int? topCount)218        {219            _query.TopCount = topCount;220221            return this;222        }223224        public IFluentQuery<T> DatabaseLock(bool useLock = true)225        {226            _query.NoLock = !useLock;227228            return this;229        }230231        public List<T> Retrieve()232        {233            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())234                .ToList();235        }209    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity210    {211        private QueryExpression _query;212        private IOrganizationService _service;213214        public FluentQuery(string entityName, IOrganizationService service)215        {216            _query = new QueryExpression217            {218                EntityName = entityName,219                NoLock = true220            };221222            _service = service;223        }224225        public IFluentQuery<T> IncludeColumns(params string[] columns)226        {227            _query.ColumnSet.AllColumns = false;228            _query.ColumnSet.AddColumns(columns);229230            return this;231        }232233        public IFluentQuery<T> IncludeAllColumns()234        {235            _query.ColumnSet.AllColumns = true;  236237        public List<T> RetrieveAll()238        {239            var records = new List<T>();240241            var previousPageNumber = _query.PageInfo.PageNumber;242            var previousPagingCookie = _query.PageInfo.PagingCookie;243244            var moreRecords = false;245            var pageNumber = previousPageNumber;246            string pagingCookie = previousPagingCookie;237            return this;238        }239240        public IFluentQuerySetting<T> With241        {242            get243            {244                return this;245            }246        }  247248            do249            {250                _query.PageInfo.PageNumber = pageNumber;251                _query.PageInfo.PagingCookie = pagingCookie;252253                var response = _service.RetrieveMultiple(_query);254                var result = response.Entities.Select(e => e.ToEntity<T>())255                    .ToList();256257                records.AddRange(result);248        public IFluentQuery<T> RecordCount(int? topCount)249        {250            _query.TopCount = topCount;251252            return this;253        }254255        public IFluentQuery<T> DatabaseLock(bool useLock = true)256        {257            _query.NoLock = !useLock;  258259                moreRecords = response.MoreRecords;260                pageNumber++;261            }262            while (moreRecords);263264            _query.PageInfo.PageNumber = previousPageNumber;265            _query.PageInfo.PagingCookie = previousPagingCookie;266267            return records;268        }269270        public IFluentQuery<T> UniqueRecords(bool unique = true)271        {272            _query.Distinct = true;273274            return this;275        }276277        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)278        {279            var link = new FluentLinkEntity();280281            definition(link);282283            _query.LinkEntities.Add(link.GetLinkEntity());284285            return this;286        }259            return this;260        }261262        public List<T> Retrieve()263        {264            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())265                .ToList();266        }267268        public List<T> RetrieveAll()269        {270            var records = new List<T>();271272            var previousPageNumber = _query.PageInfo.PageNumber;273            var previousPagingCookie = _query.PageInfo.PagingCookie;274275            var moreRecords = false;276            var pageNumber = previousPageNumber;277            string pagingCookie = previousPagingCookie;278279            do280            {281                _query.PageInfo.PageNumber = pageNumber;282                _query.PageInfo.PagingCookie = pagingCookie;283284                var response = _service.RetrieveMultiple(_query);285                var result = response.Entities.Select(e => e.ToEntity<T>())286                    .ToList();  287288        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)289        {290            var filter = new FluentFilterExpression();291292            definition(filter);293294            _query.Criteria = filter.GetFilter();295296            return this;297        }298299        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)300        {301            var order = new FluentOrderExpression();302303            definition(order);288                records.AddRange(result);289290                moreRecords = response.MoreRecords;291                pageNumber++;292            }293            while (moreRecords);294295            _query.PageInfo.PageNumber = previousPageNumber;296            _query.PageInfo.PagingCookie = previousPagingCookie;297298            return records;299        }300301        public IFluentQuery<T> UniqueRecords(bool unique = true)302        {303            _query.Distinct = true;  304305            _query.Orders.Add(order.GetOrder());306307            return this;308        }309310        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)311        {312            var PagingInfo = new FluentPagingInfo();305            return this;306        }307308        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)309        {310            var link = new FluentLinkEntity();311312            definition(link);  313314            definition(PagingInfo);314            _query.LinkEntities.Add(link.GetLinkEntity());  315316            _query.PageInfo = PagingInfo.GetPagingInfo();317318            return this;319        }320321        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)322        {323            _query.PageInfo.ReturnTotalRecordCount = true;316            return this;317        }318319        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)320        {321            var filter = new FluentFilterExpression();322323            definition(filter);  324325            return this;326        }327328        public QueryExpression Expression329        {330            get331            {332                return _query;333            }334        }335    }336337    public interface IFluentLinkEntity338    {339        /**340         * <summary>341         * Logical name of entity that the link is created from.342         * </summary>343         * <param name="entityName">Entity Logical Name</param>344         */345        IFluentLinkEntity FromEntity(string entityName);346347        /**348         * <summary>349         * Logical name of attribute that the link is created from.350         * </summary>351         * <param name="attributeName">Attribute Logical Name</param>352         */353        IFluentLinkEntity FromAttribute(string attributeName);354355        /**356         * <summary>357         * Logical name of entity that the link is created to.358         * </summary>359         * <param name="entityName">Entity Logical Name</param>360         */361        IFluentLinkEntity ToEntity(string entityName);325            _query.Criteria = filter.GetFilter();326327            return this;328        }329330        public void AddCondition(Action<IFluentConditionExpression> definition)331        {332            var condition = new FluentConditionExpression();333334            definition(condition);335336            _query.Criteria.AddCondition(condition.GetCondition());337        }338339        public void AddFilter(Action<IFluentFilterExpression> definition)340        {341            var filter = new FluentFilterExpression();342343            definition(filter);344345            _query.Criteria.AddFilter(filter.GetFilter());346        }347348        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)349        {350            var order = new FluentOrderExpression();351352            definition(order);353354            _query.Orders.Add(order.GetOrder());355356            return this;357        }358359        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)360        {361            var PagingInfo = new FluentPagingInfo();  362363        /**364         * <summary>365         * Logical name of attribute that the link is created to.366         * </summary>367         * <param name="attributeName">Attribute Logical Name</param>368         */369        IFluentLinkEntity ToAttribute(string attributeName);370371        /**372         * <summary>373         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.374         * </summary>375         * <param name="columns">Params array of your columns.</param>376         */377        IFluentLinkEntity IncludeColumns(params string[] columns);378379        /**380        * <summary>381        * Use this for setting further options of your link.382        * </summary>383        */384        IFluentLinkEntitySetting With { get; }363            definition(PagingInfo);364365            _query.PageInfo = PagingInfo.GetPagingInfo();366367            return this;368        }369370        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)371        {372            _query.PageInfo.ReturnTotalRecordCount = true;373374            return this;375        }376377        public QueryExpression Expression378        {379            get380            {381                return _query;382            }383        }384    }  385386        /**387         * <summary>388         * Adds a nested link to this link.389         * </summary>390         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>391         */392        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);393394        /**395         * <summary>396         * Adds filter conditions to your link.397         * </summary>398         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>399         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>400         */401        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);402    }386    public interface IFluentLinkEntity387    {388        /**389         * <summary>390         * Logical name of entity that the link is created from.391         * </summary>392         * <param name="entityName">Entity Logical Name</param>393         */394        IFluentLinkEntity FromEntity(string entityName);395396        /**397         * <summary>398         * Logical name of attribute that the link is created from.399         * </summary>400         * <param name="attributeName">Attribute Logical Name</param>401         */402        IFluentLinkEntity FromAttribute(string attributeName);  403404    public interface IFluentLinkEntitySetting405    {406        /**407         * <summary>408         * Sets an alias for the results of this link entity.409         * </summary>410         * <param name="name">Alias to set in results.</param>411         */412        IFluentLinkEntity Alias(string name);413414        /**415         * <summary>Join type of this link.</summary>416         * <param name="joinOperator">Join type to use.</param>404        /**405         * <summary>406         * Logical name of entity that the link is created to.407         * </summary>408         * <param name="entityName">Entity Logical Name</param>409         */410        IFluentLinkEntity ToEntity(string entityName);411412        /**413         * <summary>414         * Logical name of attribute that the link is created to.415         * </summary>416         * <param name="attributeName">Attribute Logical Name</param>  417         */418        IFluentLinkEntity LinkType(JoinOperator joinOperator);419    }420421    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting422    {423        private LinkEntity _linkEntity;424425        public FluentLinkEntity()426        {427            _linkEntity = new LinkEntity428            {429                Columns = new ColumnSet()430            };431        }432433        public IFluentLinkEntitySetting With434        {435            get436            {437                return this;438            }439        }440441        public IFluentLinkEntity Alias(string name)442        {443            _linkEntity.EntityAlias = name;444445            return this;446        }447448        public IFluentLinkEntity FromAttribute(string attributeName)449        {450            _linkEntity.LinkFromAttributeName = attributeName;451452            return this;453        }454455        public IFluentLinkEntity FromEntity(string entityName)456        {457            _linkEntity.LinkFromEntityName = entityName;458459            return this;460        }461462        public IFluentLinkEntity IncludeColumns(params string[] columns)463        {464            _linkEntity.Columns.AddColumns(columns);465466            return this;467        }468469        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)470        {471            var filter = new FluentFilterExpression();472473            definition(filter);474475            _linkEntity.LinkCriteria = filter.GetFilter();476477            return this;478        }479480        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)481        {482            var link = new FluentLinkEntity();483484            definition(link);485486            _linkEntity.LinkEntities.Add(link.GetLinkEntity());487488            return this;489        }490491        public IFluentLinkEntity LinkType(JoinOperator joinOperator)492        {493            _linkEntity.JoinOperator = joinOperator;494495            return this;496        }497498        public IFluentLinkEntity ToAttribute(string attributeName)499        {500            _linkEntity.LinkToAttributeName = attributeName;501502            return this;503        }504505        public IFluentLinkEntity ToEntity(string entityName)506        {507            _linkEntity.LinkToEntityName = entityName;508509            return this;510        }511512        internal LinkEntity GetLinkEntity()513        {514            return _linkEntity;515        }516    }418        IFluentLinkEntity ToAttribute(string attributeName);419420        /**421         * <summary>422         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.423         * </summary>424         * <param name="columns">Params array of your columns.</param>425         */426        IFluentLinkEntity IncludeColumns(params string[] columns);427428        /**429        * <summary>430        * Use this for setting further options of your link.431        * </summary>432        */433        IFluentLinkEntitySetting With { get; }434435        /**436         * <summary>437         * Adds a nested link to this link.438         * </summary>439         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>440         */441        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);442443        /**444         * <summary>445         * Adds filter conditions to your link.446         * </summary>447         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>448         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>449         */450        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);451    }452453    public interface IFluentLinkEntitySetting454    {455        /**456         * <summary>457         * Sets an alias for the results of this link entity.458         * </summary>459         * <param name="name">Alias to set in results.</param>460         */461        IFluentLinkEntity Alias(string name);462463        /**464         * <summary>Join type of this link.</summary>465         * <param name="joinOperator">Join type to use.</param>466         */467        IFluentLinkEntity LinkType(JoinOperator joinOperator);468    }469470    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting471    {472        private LinkEntity _linkEntity;473474        public FluentLinkEntity()475        {476            _linkEntity = new LinkEntity477            {478                Columns = new ColumnSet()479            };480        }481482        public IFluentLinkEntitySetting With483        {484            get485            {486                return this;487            }488        }489490        public IFluentLinkEntity Alias(string name)491        {492            _linkEntity.EntityAlias = name;493494            return this;495        }496497        public IFluentLinkEntity FromAttribute(string attributeName)498        {499            _linkEntity.LinkFromAttributeName = attributeName;500501            return this;502        }503504        public IFluentLinkEntity FromEntity(string entityName)505        {506            _linkEntity.LinkFromEntityName = entityName;507508            return this;509        }510511        public IFluentLinkEntity IncludeColumns(params string[] columns)512        {513            _linkEntity.Columns.AddColumns(columns);514515            return this;516        }  517518    public interface IFluentFilterExpression519    {520        /**521        * <summary>522        * Use this for setting further options of your filter.523        * </summary>524        */525        IFluentFilterExpressionSetting With { get; }526527        /**528        * <summary>529        * Use this for adding a condition on an attribute to your filter.530        * </summary>531        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>532        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>533        */534        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);535536        /**537         * <summary>538         * Adds nested filter conditions to your filter.539         * </summary>540         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>541         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>542         */543        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);544    }545546    public interface IFluentFilterExpressionSetting547    {548        /**549         * <summary>550         * Sets the logical operator for chaining multiple conditions in this filter.551         * </summary>552         */553        IFluentFilterExpression Operator(LogicalOperator filterOperator);554    }555556    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting557    {558        private FilterExpression _filter;559560        public FluentFilterExpression()561        {562            _filter = new FilterExpression();563        }564565        public IFluentFilterExpressionSetting With566        {567            get568            {569                return this;570            }571        }572573        public IFluentFilterExpression Operator(LogicalOperator filterOperator)574        {575            _filter.FilterOperator = filterOperator;576577            return this;578        }579580        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)581        {582            var filter = new FluentFilterExpression();583584            definition(filter);585586            _filter.Filters.Add(filter.GetFilter());587588            return this;589        }590591        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)592        {593            var condition = new FluentConditionExpression();518        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)519        {520            var filter = new FluentFilterExpression();521522            definition(filter);523524            _linkEntity.LinkCriteria = filter.GetFilter();525526            return this;527        }528529        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)530        {531            var link = new FluentLinkEntity();532533            definition(link);534535            _linkEntity.LinkEntities.Add(link.GetLinkEntity());536537            return this;538        }539540        public IFluentLinkEntity LinkType(JoinOperator joinOperator)541        {542            _linkEntity.JoinOperator = joinOperator;543544            return this;545        }546547        public IFluentLinkEntity ToAttribute(string attributeName)548        {549            _linkEntity.LinkToAttributeName = attributeName;550551            return this;552        }553554        public IFluentLinkEntity ToEntity(string entityName)555        {556            _linkEntity.LinkToEntityName = entityName;557558            return this;559        }560561        internal LinkEntity GetLinkEntity()562        {563            return _linkEntity;564        }565    }566567    public interface IFluentFilterExpression568    {569        /**570        * <summary>571        * Use this for setting further options of your filter.572        * </summary>573        */574        IFluentFilterExpressionSetting With { get; }575576        /**577        * <summary>578        * Use this for adding a condition on an attribute to your filter.579        * </summary>580        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>581        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>582        */583        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);584585        /**586         * <summary>587         * Adds nested filter conditions to your filter.588         * </summary>589         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>590         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>591         */592        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);593    }  594595            definition(condition);596597            _filter.Conditions.Add(condition.GetCondition());598599            return this;600        }601602        internal FilterExpression GetFilter()603        {604            return _filter;605        }606    }607608    public interface IFluentConditionExpression609    {610        /**611         * <summary>612         * Set the entity name that your condition attribute targets, if it is not the main entity.613         * </summary>614         * <param name="entityName">Entity Logical Name</param>615         */616        IFluentConditionExpression Of(string entityName);617618        /**619         * <summary>620         * Set the logical name of the attribute that your condition targets.621         * </summary>622         * <param name="attributeName">Attribute logical name</param>623         */624        IFluentConditionExpression Named(string attributeName);595    public interface IFluentFilterExpressionSetting596    {597        /**598         * <summary>599         * Sets the logical operator for chaining multiple conditions in this filter.600         * </summary>601         */602        IFluentFilterExpression Operator(LogicalOperator filterOperator);603    }604605    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting606    {607        private FilterExpression _filter;608609        public FluentFilterExpression()610        {611            _filter = new FilterExpression();612        }613614        public IFluentFilterExpressionSetting With615        {616            get617            {618                return this;619            }620        }621622        public IFluentFilterExpression Operator(LogicalOperator filterOperator)623        {624            _filter.FilterOperator = filterOperator;  625626        /**627         * <summary>628         * Set the condition operator for your condition.629         * </summary>630         * <param name="conditionOperator">Condition Operator Enum</param>631         */632        IFluentConditionExpression Is(ConditionOperator conditionOperator);633634        /**635         * <summary>636         * Sets the value for the condition.637         * </summary>638         * <param name="value">Single object, use object array overload if necessary.</param>639         */640        IFluentConditionExpression Value(object value);641642        /**643         * <summary>644         * Sets the values for the condition.645         * </summary>646         * <param name="value">Object array, use object overload if necessary.</param>647         */648        IFluentConditionExpression Value(params object[] value);649650        /**651         * <summary>652         * Alias for Value, provides better readability on Equal conditions.653         * Sets the value for the condition.654         * </summary>655         * <param name="value">Single object, use object array overload if necessary.</param>656         */657        IFluentConditionExpression To(object value);658626            return this;627        }628629        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)630        {631            var filter = new FluentFilterExpression();632633            definition(filter);634635            _filter.Filters.Add(filter.GetFilter());636637            return this;638        }639640        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)641        {642            var condition = new FluentConditionExpression();643644            definition(condition);645646            _filter.Conditions.Add(condition.GetCondition());647648            return this;649        }650651        internal FilterExpression GetFilter()652        {653            return _filter;654        }655    }656657    public interface IFluentConditionExpression658    {  659        /**  660         * <summary>661         * Alias for Value, provides better readability on Equal conditions.662         * Sets the values for the condition.663         * </summary>664         * <param name="value">Object array, use object overload if necessary.</param>665         */666        IFluentConditionExpression To(params object[] value);667    }668669    public class FluentConditionExpression : IFluentConditionExpression670    {671        private ConditionExpression _condition;672673        public FluentConditionExpression()674        {675            _condition = new ConditionExpression();676        }677678        public IFluentConditionExpression Is(ConditionOperator conditionOperator)679        {680            _condition.Operator = conditionOperator;681682            return this;683        }684685        public IFluentConditionExpression Named(string attributeName)686        {687            _condition.AttributeName = attributeName;688689            return this;690        }691692        public IFluentConditionExpression Of(string entityName)693        {694            _condition.EntityName = entityName;695696            return this;697        }661         * Set the entity name that your condition attribute targets, if it is not the main entity.662         * </summary>663         * <param name="entityName">Entity Logical Name</param>664         */665        IFluentConditionExpression Of(string entityName);666667        /**668         * <summary>669         * Set the logical name of the attribute that your condition targets.670         * </summary>671         * <param name="attributeName">Attribute logical name</param>672         */673        IFluentConditionExpression Named(string attributeName);674675        /**676         * <summary>677         * Set the condition operator for your condition.678         * </summary>679         * <param name="conditionOperator">Condition Operator Enum</param>680         */681        IFluentConditionExpression Is(ConditionOperator conditionOperator);682683        /**684         * <summary>685         * Sets the value for the condition.686         * </summary>687         * <param name="value">Single object, use object array overload if necessary.</param>688         */689        IFluentConditionExpression Value(object value);690691        /**692         * <summary>693         * Sets the values for the condition.694         * </summary>695         * <param name="value">Object array, use object overload if necessary.</param>696         */697        IFluentConditionExpression Value(params object[] value);  698699        public IFluentConditionExpression To(object value)700        {701            return Value(value);702        }703704        public IFluentConditionExpression To(params object[] value)705        {706            return Value(value);707        }708709        public IFluentConditionExpression Value(object value)710        {711            _condition.Values.Add(value);712713            return this;714        }715716        public IFluentConditionExpression Value(params object[] value)717        {718            _condition.Values.AddRange(value);719720            return this;721        }722723        internal ConditionExpression GetCondition ()724        {725            return _condition;726        }727    }728729    public interface IFluentOrderExpression730    {731        /**732         * <summary>733         * Set the attribute name to order by.734         * </summary>735         * <param name="attributeName">Attribute logical name</param>736         */737        IFluentOrderExpression By(string attributeName);738739        /**740         * <summary>741         * Sets the sort order to be ascending.742         * </summary>743         */744        IFluentOrderExpression Ascending();745746        /**747         * <summary>748         * Sets the sort order to be descending.749         * </summary>750         */751        IFluentOrderExpression Descending();752    }753754    public class FluentOrderExpression : IFluentOrderExpression755    {756        private OrderExpression _order;699        /**700         * <summary>701         * Alias for Value, provides better readability on Equal conditions.702         * Sets the value for the condition.703         * </summary>704         * <param name="value">Single object, use object array overload if necessary.</param>705         */706        IFluentConditionExpression To(object value);707708        /**709         * <summary>710         * Alias for Value, provides better readability on Equal conditions.711         * Sets the values for the condition.712         * </summary>713         * <param name="value">Object array, use object overload if necessary.</param>714         */715        IFluentConditionExpression To(params object[] value);716    }717718    public class FluentConditionExpression : IFluentConditionExpression719    {720        private ConditionExpression _condition;721722        public FluentConditionExpression()723        {724            _condition = new ConditionExpression();725        }726727        public IFluentConditionExpression Is(ConditionOperator conditionOperator)728        {729            _condition.Operator = conditionOperator;730731            return this;732        }733734        public IFluentConditionExpression Named(string attributeName)735        {736            _condition.AttributeName = attributeName;737738            return this;739        }740741        public IFluentConditionExpression Of(string entityName)742        {743            _condition.EntityName = entityName;744745            return this;746        }747748        public IFluentConditionExpression To(object value)749        {750            return Value(value);751        }752753        public IFluentConditionExpression To(params object[] value)754        {755            return Value(value);756        }  757 - 5758        public FluentOrderExpression () - 5759        { - 5760            _order = new OrderExpression(); - 5761        }762763        public IFluentOrderExpression By(string attributeName) - 5764        { - 5765            _order.AttributeName = attributeName;766 - 5767            return this; - 5768        }769770        public IFluentOrderExpression Ascending() - 1771        { - 1772            _order.OrderType = OrderType.Ascending;773 - 1774            return this; - 1775        }776777        public IFluentOrderExpression Descending() - 1778        { - 1779            _order.OrderType = OrderType.Descending;780 - 1781            return this; - 1782        }783784        internal OrderExpression GetOrder() - 5785        { - 5786            return _order; - 5787        }788    }789790    public interface IFluentPagingInfo791    {792        /**793         * <summary>794         * Set the page number to retrieve. Is set to 1 by default.795         * </summary>796         * <param name="number">Number of the page, starts at 1.</param>797         */798        IFluentPagingInfo PageNumber(int number);799800        /**801         * <summary>802         * Set the paging cookie for retrieving records from pages after the first.803         * </summary>804         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>805         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>806         */807        IFluentPagingInfo PagingCookie(string pagingCookie);808809        /**810         * <summary>811         * Set the size of each page.812         * </summary>813         * <param name="number">Number of records to return per page.</param>814         */815        IFluentPagingInfo PageSize(int number);816817        /**818         * <summary>819         * Specifies whether the total record count of your query results should be retrieved.820         * </summary>821         * <param name="returnTotal">True for returning total record count, false otherwise.</param>822         */823        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);824    }758        public IFluentConditionExpression Value(object value)759        {760            _condition.Values.Add(value);761762            return this;763        }764765        public IFluentConditionExpression Value(params object[] value)766        {767            _condition.Values.AddRange(value);768769            return this;770        }771772        internal ConditionExpression GetCondition ()773        {774            return _condition;775        }776    }777778    public interface IFluentOrderExpression779    {780        /**781         * <summary>782         * Set the attribute name to order by.783         * </summary>784         * <param name="attributeName">Attribute logical name</param>785         */786        IFluentOrderExpression By(string attributeName);787788        /**789         * <summary>790         * Sets the sort order to be ascending.791         * </summary>792         */793        IFluentOrderExpression Ascending();794795        /**796         * <summary>797         * Sets the sort order to be descending.798         * </summary>799         */800        IFluentOrderExpression Descending();801    }802803    public class FluentOrderExpression : IFluentOrderExpression804    {805        private OrderExpression _order;806 + 5807        public FluentOrderExpression () + 5808        { + 5809            _order = new OrderExpression(); + 5810        }811812        public IFluentOrderExpression By(string attributeName) + 5813        { + 5814            _order.AttributeName = attributeName;815 + 5816            return this; + 5817        }818819        public IFluentOrderExpression Ascending() + 1820        { + 1821            _order.OrderType = OrderType.Ascending;822 + 1823            return this; + 1824        }  825826    public class FluentPagingInfo : IFluentPagingInfo827    {828        private PagingInfo _pagingInfo;826        public IFluentOrderExpression Descending() + 1827        { + 1828            _order.OrderType = OrderType.Descending;  829830        public FluentPagingInfo()831        {832            _pagingInfo = new PagingInfo833            {834                PageNumber = 1835            };836        }837838        public IFluentPagingInfo PageNumber(int number)839        {840            _pagingInfo.PageNumber = number;841842            return this;843        }844845        public IFluentPagingInfo PageSize(int number)846        {847            _pagingInfo.Count = number; + 1830            return this; + 1831        }832833        internal OrderExpression GetOrder() + 5834        { + 5835            return _order; + 5836        }837    }838839    public interface IFluentPagingInfo840    {841        /**842         * <summary>843         * Set the page number to retrieve. Is set to 1 by default.844         * </summary>845         * <param name="number">Number of the page, starts at 1.</param>846         */847        IFluentPagingInfo PageNumber(int number);  848849            return this;850        }851852        public IFluentPagingInfo PagingCookie(string pagingCookie)853        {854            _pagingInfo.PagingCookie = pagingCookie;855856            return this;857        }858859        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)860        {861            _pagingInfo.ReturnTotalRecordCount = returnTotal;862863            return this;864        }849        /**850         * <summary>851         * Set the paging cookie for retrieving records from pages after the first.852         * </summary>853         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>854         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>855         */856        IFluentPagingInfo PagingCookie(string pagingCookie);857858        /**859         * <summary>860         * Set the size of each page.861         * </summary>862         * <param name="number">Number of records to return per page.</param>863         */864        IFluentPagingInfo PageSize(int number);  865866        public PagingInfo GetPagingInfo()867        {868            return _pagingInfo;869        }870    }871}866        /**867         * <summary>868         * Specifies whether the total record count of your query results should be retrieved.869         * </summary>870         * <param name="returnTotal">True for returning total record count, false otherwise.</param>871         */872        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);873    }874875    public class FluentPagingInfo : IFluentPagingInfo876    {877        private PagingInfo _pagingInfo;878879        public FluentPagingInfo()880        {881            _pagingInfo = new PagingInfo882            {883                PageNumber = 1884            };885        }886887        public IFluentPagingInfo PageNumber(int number)888        {889            _pagingInfo.PageNumber = number;890891            return this;892        }893894        public IFluentPagingInfo PageSize(int number)895        {896            _pagingInfo.Count = number;897898            return this;899        }900901        public IFluentPagingInfo PagingCookie(string pagingCookie)902        {903            _pagingInfo.PagingCookie = pagingCookie;904905            return this;906        }907908        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)909        {910            _pagingInfo.ReturnTotalRecordCount = returnTotal;911912            return this;913        }914915        public PagingInfo GetPagingInfo()916        {917            return _pagingInfo;918        }919    }920} - + diff --git a/reports/Xrm.Oss.FluentQuery_FluentPagingInfo.htm b/reports/Xrm.Oss.FluentQuery_FluentPagingInfo.htm index fe11af1..fc2e16f 100644 --- a/reports/Xrm.Oss.FluentQuery_FluentPagingInfo.htm +++ b/reports/Xrm.Oss.FluentQuery_FluentPagingInfo.htm @@ -20,7 +20,7 @@

Summary

Covered lines:26 Uncovered lines:0 Coverable lines:26 -Total lines:871 +Total lines:920 Line coverage:100% @@ -127,803 +127,852 @@

 84  85        /**  86         * <summary>87         * Returns the Query Expression that represents the current fluent query.87         * Adds all columns to the query. This is disadvised, specify the columns you need if possible.  88         * </summary>  89         */90        QueryExpression Expression { get; }90        IFluentQuery<T> IncludeAllColumns();  91  92        /**  93         * <summary>94         * Retrieves the first page for your query.94         * Returns the Query Expression that represents the current fluent query.  95         * </summary>96         * <returns>Records retrieved from your query.</returns>97         */98        List<T> Retrieve();99100        /**101         * <summary>102         * Retrieves all pages for your query.103         * </summary>104         * <returns>Records retrieved from your query.</returns>105         */106        List<T> RetrieveAll();107108        /**109         * <summary>110         * Use this for setting further options in your query.111         * </summary>96         */97        QueryExpression Expression { get; }9899        /**100         * <summary>101         * Retrieves the first page for your query.102         * </summary>103         * <returns>Records retrieved from your query.</returns>104         */105        List<T> Retrieve();106107        /**108         * <summary>109         * Retrieves all pages for your query.110         * </summary>111         * <returns>Records retrieved from your query.</returns>  112         */113        IFluentQuerySetting<T> With { get; }113        List<T> RetrieveAll();  114  115        /**  116         * <summary>117         * Adds a link to a connected entity.117         * Use this for setting further options in your query.  118         * </summary>119         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>120         */121        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);122123        /**124         * <summary>125         * Adds filter conditions to your query.126         * </summary>127         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>128         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>129         */130        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);131132        /**133         * <summary>134         * Adds an order expression to your query.135         * </summary>136         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>137         */138        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);139    }140141    public interface IFluentQuerySetting<T> where T : Entity142    {143        /**144         * <summary>145         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.146         * </summary>147         * <param name="topCount">Top X count of records to retrieve</param>148         */149        IFluentQuery<T> RecordCount(int? topCount);150151        /**152         * <summary>153         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi154         * </summary>155         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 156         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>157         */158        IFluentQuery<T> DatabaseLock(bool useLock = true);159160        /**161         * <summary>162         * Specifies whether duplicate records in your query will be filtered out or not.163         * </summary>164         * <param name="unique">True for only returning unique records, false otherwise</param>165         */166        IFluentQuery<T> UniqueRecords(bool unique = true);167168        /**169         * <summary>170         * Adds paging info to your query, such as page size, page number or paging cookie.171         * </summary>172         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>173         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>174         */175        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);176177        /**178         * <summary>179         * Specifies whether the total record count of your query results should be retrieved.180         * </summary>181         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>182         */183        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);184    }185186    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity187    {188        private QueryExpression _query;189        private IOrganizationService _service;119         */120        IFluentQuerySetting<T> With { get; }121122        /**123         * <summary>124         * Adds a link to a connected entity.125         * </summary>126         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>127         */128        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);129130        /**131         * <summary>132         * Adds filter conditions to your query.133         * </summary>134         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>135         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>136         */137        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);138139        /**140         * <summary>141         * Adds another condition to the top level filter expression.142         * </summary>143         * <param name="definition">The condition expression to add.</param>144         */145        void AddCondition(Action<IFluentConditionExpression> definition);146147        /**148         * <summary>149         * Adds a child filter to your top level filter.150         * </summary>151         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>152         */153        void AddFilter(Action<IFluentFilterExpression> definition);154155        /**156         * <summary>157         * Adds an order expression to your query.158         * </summary>159         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>160         */161        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);162    }163164    public interface IFluentQuerySetting<T> where T : Entity165    {166        /**167         * <summary>168         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.169         * </summary>170         * <param name="topCount">Top X count of records to retrieve</param>171         */172        IFluentQuery<T> RecordCount(int? topCount);173174        /**175         * <summary>176         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi177         * </summary>178         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 179         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>180         */181        IFluentQuery<T> DatabaseLock(bool useLock = true);182183        /**184         * <summary>185         * Specifies whether duplicate records in your query will be filtered out or not.186         * </summary>187         * <param name="unique">True for only returning unique records, false otherwise</param>188         */189        IFluentQuery<T> UniqueRecords(bool unique = true);  190191        public FluentQuery(string entityName, IOrganizationService service)192        {193            _query = new QueryExpression194            {195                EntityName = entityName,196                NoLock = true197            };198199            _service = service;200        }201202        public IFluentQuery<T> IncludeColumns(params string[] columns)203        {204            _query.ColumnSet.AddColumns(columns);205206            return this;207        }191        /**192         * <summary>193         * Adds paging info to your query, such as page size, page number or paging cookie.194         * </summary>195         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>196         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>197         */198        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);199200        /**201         * <summary>202         * Specifies whether the total record count of your query results should be retrieved.203         * </summary>204         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>205         */206        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);207    }  208209        public IFluentQuerySetting<T> With210        {211            get212            {213                return this;214            }215        }216217        public IFluentQuery<T> RecordCount(int? topCount)218        {219            _query.TopCount = topCount;220221            return this;222        }223224        public IFluentQuery<T> DatabaseLock(bool useLock = true)225        {226            _query.NoLock = !useLock;227228            return this;229        }230231        public List<T> Retrieve()232        {233            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())234                .ToList();235        }209    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity210    {211        private QueryExpression _query;212        private IOrganizationService _service;213214        public FluentQuery(string entityName, IOrganizationService service)215        {216            _query = new QueryExpression217            {218                EntityName = entityName,219                NoLock = true220            };221222            _service = service;223        }224225        public IFluentQuery<T> IncludeColumns(params string[] columns)226        {227            _query.ColumnSet.AllColumns = false;228            _query.ColumnSet.AddColumns(columns);229230            return this;231        }232233        public IFluentQuery<T> IncludeAllColumns()234        {235            _query.ColumnSet.AllColumns = true;  236237        public List<T> RetrieveAll()238        {239            var records = new List<T>();240241            var previousPageNumber = _query.PageInfo.PageNumber;242            var previousPagingCookie = _query.PageInfo.PagingCookie;243244            var moreRecords = false;245            var pageNumber = previousPageNumber;246            string pagingCookie = previousPagingCookie;237            return this;238        }239240        public IFluentQuerySetting<T> With241        {242            get243            {244                return this;245            }246        }  247248            do249            {250                _query.PageInfo.PageNumber = pageNumber;251                _query.PageInfo.PagingCookie = pagingCookie;252253                var response = _service.RetrieveMultiple(_query);254                var result = response.Entities.Select(e => e.ToEntity<T>())255                    .ToList();256257                records.AddRange(result);248        public IFluentQuery<T> RecordCount(int? topCount)249        {250            _query.TopCount = topCount;251252            return this;253        }254255        public IFluentQuery<T> DatabaseLock(bool useLock = true)256        {257            _query.NoLock = !useLock;  258259                moreRecords = response.MoreRecords;260                pageNumber++;261            }262            while (moreRecords);263264            _query.PageInfo.PageNumber = previousPageNumber;265            _query.PageInfo.PagingCookie = previousPagingCookie;266267            return records;268        }269270        public IFluentQuery<T> UniqueRecords(bool unique = true)271        {272            _query.Distinct = true;273274            return this;275        }276277        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)278        {279            var link = new FluentLinkEntity();280281            definition(link);282283            _query.LinkEntities.Add(link.GetLinkEntity());284285            return this;286        }259            return this;260        }261262        public List<T> Retrieve()263        {264            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())265                .ToList();266        }267268        public List<T> RetrieveAll()269        {270            var records = new List<T>();271272            var previousPageNumber = _query.PageInfo.PageNumber;273            var previousPagingCookie = _query.PageInfo.PagingCookie;274275            var moreRecords = false;276            var pageNumber = previousPageNumber;277            string pagingCookie = previousPagingCookie;278279            do280            {281                _query.PageInfo.PageNumber = pageNumber;282                _query.PageInfo.PagingCookie = pagingCookie;283284                var response = _service.RetrieveMultiple(_query);285                var result = response.Entities.Select(e => e.ToEntity<T>())286                    .ToList();  287288        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)289        {290            var filter = new FluentFilterExpression();291292            definition(filter);293294            _query.Criteria = filter.GetFilter();295296            return this;297        }298299        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)300        {301            var order = new FluentOrderExpression();302303            definition(order);288                records.AddRange(result);289290                moreRecords = response.MoreRecords;291                pageNumber++;292            }293            while (moreRecords);294295            _query.PageInfo.PageNumber = previousPageNumber;296            _query.PageInfo.PagingCookie = previousPagingCookie;297298            return records;299        }300301        public IFluentQuery<T> UniqueRecords(bool unique = true)302        {303            _query.Distinct = true;  304305            _query.Orders.Add(order.GetOrder());306307            return this;308        }309310        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)311        {312            var PagingInfo = new FluentPagingInfo();305            return this;306        }307308        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)309        {310            var link = new FluentLinkEntity();311312            definition(link);  313314            definition(PagingInfo);314            _query.LinkEntities.Add(link.GetLinkEntity());  315316            _query.PageInfo = PagingInfo.GetPagingInfo();317318            return this;319        }320321        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)322        {323            _query.PageInfo.ReturnTotalRecordCount = true;316            return this;317        }318319        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)320        {321            var filter = new FluentFilterExpression();322323            definition(filter);  324325            return this;326        }327328        public QueryExpression Expression329        {330            get331            {332                return _query;333            }334        }335    }336337    public interface IFluentLinkEntity338    {339        /**340         * <summary>341         * Logical name of entity that the link is created from.342         * </summary>343         * <param name="entityName">Entity Logical Name</param>344         */345        IFluentLinkEntity FromEntity(string entityName);346347        /**348         * <summary>349         * Logical name of attribute that the link is created from.350         * </summary>351         * <param name="attributeName">Attribute Logical Name</param>352         */353        IFluentLinkEntity FromAttribute(string attributeName);354355        /**356         * <summary>357         * Logical name of entity that the link is created to.358         * </summary>359         * <param name="entityName">Entity Logical Name</param>360         */361        IFluentLinkEntity ToEntity(string entityName);325            _query.Criteria = filter.GetFilter();326327            return this;328        }329330        public void AddCondition(Action<IFluentConditionExpression> definition)331        {332            var condition = new FluentConditionExpression();333334            definition(condition);335336            _query.Criteria.AddCondition(condition.GetCondition());337        }338339        public void AddFilter(Action<IFluentFilterExpression> definition)340        {341            var filter = new FluentFilterExpression();342343            definition(filter);344345            _query.Criteria.AddFilter(filter.GetFilter());346        }347348        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)349        {350            var order = new FluentOrderExpression();351352            definition(order);353354            _query.Orders.Add(order.GetOrder());355356            return this;357        }358359        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)360        {361            var PagingInfo = new FluentPagingInfo();  362363        /**364         * <summary>365         * Logical name of attribute that the link is created to.366         * </summary>367         * <param name="attributeName">Attribute Logical Name</param>368         */369        IFluentLinkEntity ToAttribute(string attributeName);370371        /**372         * <summary>373         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.374         * </summary>375         * <param name="columns">Params array of your columns.</param>376         */377        IFluentLinkEntity IncludeColumns(params string[] columns);378379        /**380        * <summary>381        * Use this for setting further options of your link.382        * </summary>383        */384        IFluentLinkEntitySetting With { get; }363            definition(PagingInfo);364365            _query.PageInfo = PagingInfo.GetPagingInfo();366367            return this;368        }369370        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)371        {372            _query.PageInfo.ReturnTotalRecordCount = true;373374            return this;375        }376377        public QueryExpression Expression378        {379            get380            {381                return _query;382            }383        }384    }  385386        /**387         * <summary>388         * Adds a nested link to this link.389         * </summary>390         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>391         */392        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);393394        /**395         * <summary>396         * Adds filter conditions to your link.397         * </summary>398         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>399         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>400         */401        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);402    }386    public interface IFluentLinkEntity387    {388        /**389         * <summary>390         * Logical name of entity that the link is created from.391         * </summary>392         * <param name="entityName">Entity Logical Name</param>393         */394        IFluentLinkEntity FromEntity(string entityName);395396        /**397         * <summary>398         * Logical name of attribute that the link is created from.399         * </summary>400         * <param name="attributeName">Attribute Logical Name</param>401         */402        IFluentLinkEntity FromAttribute(string attributeName);  403404    public interface IFluentLinkEntitySetting405    {406        /**407         * <summary>408         * Sets an alias for the results of this link entity.409         * </summary>410         * <param name="name">Alias to set in results.</param>411         */412        IFluentLinkEntity Alias(string name);413414        /**415         * <summary>Join type of this link.</summary>416         * <param name="joinOperator">Join type to use.</param>404        /**405         * <summary>406         * Logical name of entity that the link is created to.407         * </summary>408         * <param name="entityName">Entity Logical Name</param>409         */410        IFluentLinkEntity ToEntity(string entityName);411412        /**413         * <summary>414         * Logical name of attribute that the link is created to.415         * </summary>416         * <param name="attributeName">Attribute Logical Name</param>  417         */418        IFluentLinkEntity LinkType(JoinOperator joinOperator);419    }420421    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting422    {423        private LinkEntity _linkEntity;424425        public FluentLinkEntity()426        {427            _linkEntity = new LinkEntity428            {429                Columns = new ColumnSet()430            };431        }432433        public IFluentLinkEntitySetting With434        {435            get436            {437                return this;438            }439        }440441        public IFluentLinkEntity Alias(string name)442        {443            _linkEntity.EntityAlias = name;444445            return this;446        }447448        public IFluentLinkEntity FromAttribute(string attributeName)449        {450            _linkEntity.LinkFromAttributeName = attributeName;451452            return this;453        }454455        public IFluentLinkEntity FromEntity(string entityName)456        {457            _linkEntity.LinkFromEntityName = entityName;458459            return this;460        }461462        public IFluentLinkEntity IncludeColumns(params string[] columns)463        {464            _linkEntity.Columns.AddColumns(columns);465466            return this;467        }468469        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)470        {471            var filter = new FluentFilterExpression();472473            definition(filter);474475            _linkEntity.LinkCriteria = filter.GetFilter();476477            return this;478        }479480        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)481        {482            var link = new FluentLinkEntity();483484            definition(link);485486            _linkEntity.LinkEntities.Add(link.GetLinkEntity());487488            return this;489        }490491        public IFluentLinkEntity LinkType(JoinOperator joinOperator)492        {493            _linkEntity.JoinOperator = joinOperator;494495            return this;496        }497498        public IFluentLinkEntity ToAttribute(string attributeName)499        {500            _linkEntity.LinkToAttributeName = attributeName;501502            return this;503        }504505        public IFluentLinkEntity ToEntity(string entityName)506        {507            _linkEntity.LinkToEntityName = entityName;508509            return this;510        }511512        internal LinkEntity GetLinkEntity()513        {514            return _linkEntity;515        }516    }418        IFluentLinkEntity ToAttribute(string attributeName);419420        /**421         * <summary>422         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.423         * </summary>424         * <param name="columns">Params array of your columns.</param>425         */426        IFluentLinkEntity IncludeColumns(params string[] columns);427428        /**429        * <summary>430        * Use this for setting further options of your link.431        * </summary>432        */433        IFluentLinkEntitySetting With { get; }434435        /**436         * <summary>437         * Adds a nested link to this link.438         * </summary>439         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>440         */441        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);442443        /**444         * <summary>445         * Adds filter conditions to your link.446         * </summary>447         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>448         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>449         */450        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);451    }452453    public interface IFluentLinkEntitySetting454    {455        /**456         * <summary>457         * Sets an alias for the results of this link entity.458         * </summary>459         * <param name="name">Alias to set in results.</param>460         */461        IFluentLinkEntity Alias(string name);462463        /**464         * <summary>Join type of this link.</summary>465         * <param name="joinOperator">Join type to use.</param>466         */467        IFluentLinkEntity LinkType(JoinOperator joinOperator);468    }469470    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting471    {472        private LinkEntity _linkEntity;473474        public FluentLinkEntity()475        {476            _linkEntity = new LinkEntity477            {478                Columns = new ColumnSet()479            };480        }481482        public IFluentLinkEntitySetting With483        {484            get485            {486                return this;487            }488        }489490        public IFluentLinkEntity Alias(string name)491        {492            _linkEntity.EntityAlias = name;493494            return this;495        }496497        public IFluentLinkEntity FromAttribute(string attributeName)498        {499            _linkEntity.LinkFromAttributeName = attributeName;500501            return this;502        }503504        public IFluentLinkEntity FromEntity(string entityName)505        {506            _linkEntity.LinkFromEntityName = entityName;507508            return this;509        }510511        public IFluentLinkEntity IncludeColumns(params string[] columns)512        {513            _linkEntity.Columns.AddColumns(columns);514515            return this;516        }  517518    public interface IFluentFilterExpression519    {520        /**521        * <summary>522        * Use this for setting further options of your filter.523        * </summary>524        */525        IFluentFilterExpressionSetting With { get; }526527        /**528        * <summary>529        * Use this for adding a condition on an attribute to your filter.530        * </summary>531        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>532        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>533        */534        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);535536        /**537         * <summary>538         * Adds nested filter conditions to your filter.539         * </summary>540         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>541         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>542         */543        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);544    }545546    public interface IFluentFilterExpressionSetting547    {548        /**549         * <summary>550         * Sets the logical operator for chaining multiple conditions in this filter.551         * </summary>552         */553        IFluentFilterExpression Operator(LogicalOperator filterOperator);554    }555556    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting557    {558        private FilterExpression _filter;559560        public FluentFilterExpression()561        {562            _filter = new FilterExpression();563        }564565        public IFluentFilterExpressionSetting With566        {567            get568            {569                return this;570            }571        }572573        public IFluentFilterExpression Operator(LogicalOperator filterOperator)574        {575            _filter.FilterOperator = filterOperator;576577            return this;578        }579580        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)581        {582            var filter = new FluentFilterExpression();583584            definition(filter);585586            _filter.Filters.Add(filter.GetFilter());587588            return this;589        }590591        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)592        {593            var condition = new FluentConditionExpression();518        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)519        {520            var filter = new FluentFilterExpression();521522            definition(filter);523524            _linkEntity.LinkCriteria = filter.GetFilter();525526            return this;527        }528529        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)530        {531            var link = new FluentLinkEntity();532533            definition(link);534535            _linkEntity.LinkEntities.Add(link.GetLinkEntity());536537            return this;538        }539540        public IFluentLinkEntity LinkType(JoinOperator joinOperator)541        {542            _linkEntity.JoinOperator = joinOperator;543544            return this;545        }546547        public IFluentLinkEntity ToAttribute(string attributeName)548        {549            _linkEntity.LinkToAttributeName = attributeName;550551            return this;552        }553554        public IFluentLinkEntity ToEntity(string entityName)555        {556            _linkEntity.LinkToEntityName = entityName;557558            return this;559        }560561        internal LinkEntity GetLinkEntity()562        {563            return _linkEntity;564        }565    }566567    public interface IFluentFilterExpression568    {569        /**570        * <summary>571        * Use this for setting further options of your filter.572        * </summary>573        */574        IFluentFilterExpressionSetting With { get; }575576        /**577        * <summary>578        * Use this for adding a condition on an attribute to your filter.579        * </summary>580        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>581        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>582        */583        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);584585        /**586         * <summary>587         * Adds nested filter conditions to your filter.588         * </summary>589         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>590         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>591         */592        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);593    }  594595            definition(condition);596597            _filter.Conditions.Add(condition.GetCondition());598599            return this;600        }601602        internal FilterExpression GetFilter()603        {604            return _filter;605        }606    }607608    public interface IFluentConditionExpression609    {610        /**611         * <summary>612         * Set the entity name that your condition attribute targets, if it is not the main entity.613         * </summary>614         * <param name="entityName">Entity Logical Name</param>615         */616        IFluentConditionExpression Of(string entityName);617618        /**619         * <summary>620         * Set the logical name of the attribute that your condition targets.621         * </summary>622         * <param name="attributeName">Attribute logical name</param>623         */624        IFluentConditionExpression Named(string attributeName);595    public interface IFluentFilterExpressionSetting596    {597        /**598         * <summary>599         * Sets the logical operator for chaining multiple conditions in this filter.600         * </summary>601         */602        IFluentFilterExpression Operator(LogicalOperator filterOperator);603    }604605    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting606    {607        private FilterExpression _filter;608609        public FluentFilterExpression()610        {611            _filter = new FilterExpression();612        }613614        public IFluentFilterExpressionSetting With615        {616            get617            {618                return this;619            }620        }621622        public IFluentFilterExpression Operator(LogicalOperator filterOperator)623        {624            _filter.FilterOperator = filterOperator;  625626        /**627         * <summary>628         * Set the condition operator for your condition.629         * </summary>630         * <param name="conditionOperator">Condition Operator Enum</param>631         */632        IFluentConditionExpression Is(ConditionOperator conditionOperator);633634        /**635         * <summary>636         * Sets the value for the condition.637         * </summary>638         * <param name="value">Single object, use object array overload if necessary.</param>639         */640        IFluentConditionExpression Value(object value);641642        /**643         * <summary>644         * Sets the values for the condition.645         * </summary>646         * <param name="value">Object array, use object overload if necessary.</param>647         */648        IFluentConditionExpression Value(params object[] value);649650        /**651         * <summary>652         * Alias for Value, provides better readability on Equal conditions.653         * Sets the value for the condition.654         * </summary>655         * <param name="value">Single object, use object array overload if necessary.</param>656         */657        IFluentConditionExpression To(object value);658626            return this;627        }628629        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)630        {631            var filter = new FluentFilterExpression();632633            definition(filter);634635            _filter.Filters.Add(filter.GetFilter());636637            return this;638        }639640        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)641        {642            var condition = new FluentConditionExpression();643644            definition(condition);645646            _filter.Conditions.Add(condition.GetCondition());647648            return this;649        }650651        internal FilterExpression GetFilter()652        {653            return _filter;654        }655    }656657    public interface IFluentConditionExpression658    {  659        /**  660         * <summary>661         * Alias for Value, provides better readability on Equal conditions.662         * Sets the values for the condition.663         * </summary>664         * <param name="value">Object array, use object overload if necessary.</param>665         */666        IFluentConditionExpression To(params object[] value);667    }668669    public class FluentConditionExpression : IFluentConditionExpression670    {671        private ConditionExpression _condition;672673        public FluentConditionExpression()674        {675            _condition = new ConditionExpression();676        }677678        public IFluentConditionExpression Is(ConditionOperator conditionOperator)679        {680            _condition.Operator = conditionOperator;681682            return this;683        }684685        public IFluentConditionExpression Named(string attributeName)686        {687            _condition.AttributeName = attributeName;688689            return this;690        }691692        public IFluentConditionExpression Of(string entityName)693        {694            _condition.EntityName = entityName;695696            return this;697        }661         * Set the entity name that your condition attribute targets, if it is not the main entity.662         * </summary>663         * <param name="entityName">Entity Logical Name</param>664         */665        IFluentConditionExpression Of(string entityName);666667        /**668         * <summary>669         * Set the logical name of the attribute that your condition targets.670         * </summary>671         * <param name="attributeName">Attribute logical name</param>672         */673        IFluentConditionExpression Named(string attributeName);674675        /**676         * <summary>677         * Set the condition operator for your condition.678         * </summary>679         * <param name="conditionOperator">Condition Operator Enum</param>680         */681        IFluentConditionExpression Is(ConditionOperator conditionOperator);682683        /**684         * <summary>685         * Sets the value for the condition.686         * </summary>687         * <param name="value">Single object, use object array overload if necessary.</param>688         */689        IFluentConditionExpression Value(object value);690691        /**692         * <summary>693         * Sets the values for the condition.694         * </summary>695         * <param name="value">Object array, use object overload if necessary.</param>696         */697        IFluentConditionExpression Value(params object[] value);  698699        public IFluentConditionExpression To(object value)700        {701            return Value(value);702        }703704        public IFluentConditionExpression To(params object[] value)705        {706            return Value(value);707        }708709        public IFluentConditionExpression Value(object value)710        {711            _condition.Values.Add(value);712713            return this;714        }715716        public IFluentConditionExpression Value(params object[] value)717        {718            _condition.Values.AddRange(value);719720            return this;721        }722723        internal ConditionExpression GetCondition ()724        {725            return _condition;726        }727    }728729    public interface IFluentOrderExpression730    {731        /**732         * <summary>733         * Set the attribute name to order by.734         * </summary>735         * <param name="attributeName">Attribute logical name</param>736         */737        IFluentOrderExpression By(string attributeName);738739        /**740         * <summary>741         * Sets the sort order to be ascending.742         * </summary>743         */744        IFluentOrderExpression Ascending();745746        /**747         * <summary>748         * Sets the sort order to be descending.749         * </summary>750         */751        IFluentOrderExpression Descending();752    }753754    public class FluentOrderExpression : IFluentOrderExpression755    {756        private OrderExpression _order;699        /**700         * <summary>701         * Alias for Value, provides better readability on Equal conditions.702         * Sets the value for the condition.703         * </summary>704         * <param name="value">Single object, use object array overload if necessary.</param>705         */706        IFluentConditionExpression To(object value);707708        /**709         * <summary>710         * Alias for Value, provides better readability on Equal conditions.711         * Sets the values for the condition.712         * </summary>713         * <param name="value">Object array, use object overload if necessary.</param>714         */715        IFluentConditionExpression To(params object[] value);716    }717718    public class FluentConditionExpression : IFluentConditionExpression719    {720        private ConditionExpression _condition;721722        public FluentConditionExpression()723        {724            _condition = new ConditionExpression();725        }726727        public IFluentConditionExpression Is(ConditionOperator conditionOperator)728        {729            _condition.Operator = conditionOperator;730731            return this;732        }733734        public IFluentConditionExpression Named(string attributeName)735        {736            _condition.AttributeName = attributeName;737738            return this;739        }740741        public IFluentConditionExpression Of(string entityName)742        {743            _condition.EntityName = entityName;744745            return this;746        }747748        public IFluentConditionExpression To(object value)749        {750            return Value(value);751        }752753        public IFluentConditionExpression To(params object[] value)754        {755            return Value(value);756        }  757758        public FluentOrderExpression ()758        public IFluentConditionExpression Value(object value)  759        {760            _order = new OrderExpression();761        }762763        public IFluentOrderExpression By(string attributeName)764        {765            _order.AttributeName = attributeName;766767            return this;768        }769770        public IFluentOrderExpression Ascending()771        {772            _order.OrderType = OrderType.Ascending;773774            return this;760            _condition.Values.Add(value);761762            return this;763        }764765        public IFluentConditionExpression Value(params object[] value)766        {767            _condition.Values.AddRange(value);768769            return this;770        }771772        internal ConditionExpression GetCondition ()773        {774            return _condition;  775        }776777        public IFluentOrderExpression Descending()778        {779            _order.OrderType = OrderType.Descending;780781            return this;782        }783784        internal OrderExpression GetOrder()785        {786            return _order;787        }788    }789790    public interface IFluentPagingInfo791    {792        /**793         * <summary>794         * Set the page number to retrieve. Is set to 1 by default.795         * </summary>796         * <param name="number">Number of the page, starts at 1.</param>797         */798        IFluentPagingInfo PageNumber(int number);799800        /**801         * <summary>802         * Set the paging cookie for retrieving records from pages after the first.803         * </summary>804         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>805         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>806         */807        IFluentPagingInfo PagingCookie(string pagingCookie);808809        /**810         * <summary>811         * Set the size of each page.812         * </summary>813         * <param name="number">Number of records to return per page.</param>814         */815        IFluentPagingInfo PageSize(int number);816817        /**818         * <summary>819         * Specifies whether the total record count of your query results should be retrieved.820         * </summary>821         * <param name="returnTotal">True for returning total record count, false otherwise.</param>822         */823        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);824    }776    }777778    public interface IFluentOrderExpression779    {780        /**781         * <summary>782         * Set the attribute name to order by.783         * </summary>784         * <param name="attributeName">Attribute logical name</param>785         */786        IFluentOrderExpression By(string attributeName);787788        /**789         * <summary>790         * Sets the sort order to be ascending.791         * </summary>792         */793        IFluentOrderExpression Ascending();794795        /**796         * <summary>797         * Sets the sort order to be descending.798         * </summary>799         */800        IFluentOrderExpression Descending();801    }802803    public class FluentOrderExpression : IFluentOrderExpression804    {805        private OrderExpression _order;806807        public FluentOrderExpression ()808        {809            _order = new OrderExpression();810        }811812        public IFluentOrderExpression By(string attributeName)813        {814            _order.AttributeName = attributeName;815816            return this;817        }818819        public IFluentOrderExpression Ascending()820        {821            _order.OrderType = OrderType.Ascending;822823            return this;824        }  825826    public class FluentPagingInfo : IFluentPagingInfo827    {828        private PagingInfo _pagingInfo;826        public IFluentOrderExpression Descending()827        {828            _order.OrderType = OrderType.Descending;  829 - 3830        public FluentPagingInfo() - 3831        { - 3832            _pagingInfo = new PagingInfo - 3833            { - 3834                PageNumber = 1 - 3835            }; - 3836        }837838        public IFluentPagingInfo PageNumber(int number) - 3839        { - 3840            _pagingInfo.PageNumber = number;841 - 3842            return this; - 3843        }844845        public IFluentPagingInfo PageSize(int number) - 2846        { - 2847            _pagingInfo.Count = number;830            return this;831        }832833        internal OrderExpression GetOrder()834        {835            return _order;836        }837    }838839    public interface IFluentPagingInfo840    {841        /**842         * <summary>843         * Set the page number to retrieve. Is set to 1 by default.844         * </summary>845         * <param name="number">Number of the page, starts at 1.</param>846         */847        IFluentPagingInfo PageNumber(int number);  848 - 2849            return this; - 2850        }851852        public IFluentPagingInfo PagingCookie(string pagingCookie) - 1853        { - 1854            _pagingInfo.PagingCookie = pagingCookie;855 - 1856            return this; - 1857        }858859        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true) - 1860        { - 1861            _pagingInfo.ReturnTotalRecordCount = returnTotal;862 - 1863            return this; - 1864        }849        /**850         * <summary>851         * Set the paging cookie for retrieving records from pages after the first.852         * </summary>853         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>854         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>855         */856        IFluentPagingInfo PagingCookie(string pagingCookie);857858        /**859         * <summary>860         * Set the size of each page.861         * </summary>862         * <param name="number">Number of records to return per page.</param>863         */864        IFluentPagingInfo PageSize(int number);  865866        public PagingInfo GetPagingInfo() - 3867        { - 3868            return _pagingInfo; - 3869        }870    }871}866        /**867         * <summary>868         * Specifies whether the total record count of your query results should be retrieved.869         * </summary>870         * <param name="returnTotal">True for returning total record count, false otherwise.</param>871         */872        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);873    }874875    public class FluentPagingInfo : IFluentPagingInfo876    {877        private PagingInfo _pagingInfo;878 + 3879        public FluentPagingInfo() + 3880        { + 3881            _pagingInfo = new PagingInfo + 3882            { + 3883                PageNumber = 1 + 3884            }; + 3885        }886887        public IFluentPagingInfo PageNumber(int number) + 3888        { + 3889            _pagingInfo.PageNumber = number;890 + 3891            return this; + 3892        }893894        public IFluentPagingInfo PageSize(int number) + 2895        { + 2896            _pagingInfo.Count = number;897 + 2898            return this; + 2899        }900901        public IFluentPagingInfo PagingCookie(string pagingCookie) + 1902        { + 1903            _pagingInfo.PagingCookie = pagingCookie;904 + 1905            return this; + 1906        }907908        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true) + 1909        { + 1910            _pagingInfo.ReturnTotalRecordCount = returnTotal;911 + 1912            return this; + 1913        }914915        public PagingInfo GetPagingInfo() + 3916        { + 3917            return _pagingInfo; + 3918        }919    }920} - + diff --git a/reports/Xrm.Oss.FluentQuery_FluentQuery_1.htm b/reports/Xrm.Oss.FluentQuery_FluentQuery_1.htm index 6706f0e..12743e7 100644 --- a/reports/Xrm.Oss.FluentQuery_FluentQuery_1.htm +++ b/reports/Xrm.Oss.FluentQuery_FluentQuery_1.htm @@ -17,10 +17,10 @@

Summary

Class:Xrm.Oss.FluentQuery.FluentQuery`1 Assembly:Xrm.Oss.FluentQuery File(s):C:\Users\Florian\Entwicklung\Xrm-Fluent-Query\src\lib\Xrm.Oss.FluentQuery\FluentQuery.cs -Covered lines:85 +Covered lines:100 Uncovered lines:0 -Coverable lines:85 -Total lines:871 +Coverable lines:100 +Total lines:920 Line coverage:100% Branch coverage:50% @@ -31,6 +31,7 @@

Metrics

.ctor(...)10100100 IncludeColumns(...)10100100 +IncludeAllColumns()10100100 RecordCount(...)10100100 DatabaseLock(...)10100100 Retrieve()20100100 @@ -38,6 +39,8 @@

Metrics

UniqueRecords(...)10100100 Link(...)10100100 Where(...)10100100 +AddCondition(...)10100100 +AddFilter(...)10100100 Order(...)10100100 PagingInfo(...)10100100 TotalRecordCount(...)10100100 @@ -134,811 +137,863 @@

 84  85        /**  86         * <summary>87         * Returns the Query Expression that represents the current fluent query.87         * Adds all columns to the query. This is disadvised, specify the columns you need if possible.  88         * </summary>  89         */90        QueryExpression Expression { get; }90        IFluentQuery<T> IncludeAllColumns();  91  92        /**  93         * <summary>94         * Retrieves the first page for your query.94         * Returns the Query Expression that represents the current fluent query.  95         * </summary>96         * <returns>Records retrieved from your query.</returns>97         */98        List<T> Retrieve();99100        /**101         * <summary>102         * Retrieves all pages for your query.103         * </summary>104         * <returns>Records retrieved from your query.</returns>105         */106        List<T> RetrieveAll();107108        /**109         * <summary>110         * Use this for setting further options in your query.111         * </summary>96         */97        QueryExpression Expression { get; }9899        /**100         * <summary>101         * Retrieves the first page for your query.102         * </summary>103         * <returns>Records retrieved from your query.</returns>104         */105        List<T> Retrieve();106107        /**108         * <summary>109         * Retrieves all pages for your query.110         * </summary>111         * <returns>Records retrieved from your query.</returns>  112         */113        IFluentQuerySetting<T> With { get; }113        List<T> RetrieveAll();  114  115        /**  116         * <summary>117         * Adds a link to a connected entity.117         * Use this for setting further options in your query.  118         * </summary>119         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>120         */121        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);122123        /**124         * <summary>125         * Adds filter conditions to your query.126         * </summary>127         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>128         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>129         */130        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);131132        /**133         * <summary>134         * Adds an order expression to your query.135         * </summary>136         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>137         */138        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);139    }140141    public interface IFluentQuerySetting<T> where T : Entity142    {143        /**144         * <summary>145         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.146         * </summary>147         * <param name="topCount">Top X count of records to retrieve</param>148         */149        IFluentQuery<T> RecordCount(int? topCount);150151        /**152         * <summary>153         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi154         * </summary>155         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 156         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>157         */158        IFluentQuery<T> DatabaseLock(bool useLock = true);159160        /**161         * <summary>162         * Specifies whether duplicate records in your query will be filtered out or not.163         * </summary>164         * <param name="unique">True for only returning unique records, false otherwise</param>165         */166        IFluentQuery<T> UniqueRecords(bool unique = true);167168        /**169         * <summary>170         * Adds paging info to your query, such as page size, page number or paging cookie.171         * </summary>172         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>173         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>174         */175        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);176177        /**178         * <summary>179         * Specifies whether the total record count of your query results should be retrieved.180         * </summary>181         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>182         */183        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);184    }185186    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity187    {188        private QueryExpression _query;189        private IOrganizationService _service;119         */120        IFluentQuerySetting<T> With { get; }121122        /**123         * <summary>124         * Adds a link to a connected entity.125         * </summary>126         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>127         */128        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);129130        /**131         * <summary>132         * Adds filter conditions to your query.133         * </summary>134         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>135         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>136         */137        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);138139        /**140         * <summary>141         * Adds another condition to the top level filter expression.142         * </summary>143         * <param name="definition">The condition expression to add.</param>144         */145        void AddCondition(Action<IFluentConditionExpression> definition);146147        /**148         * <summary>149         * Adds a child filter to your top level filter.150         * </summary>151         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>152         */153        void AddFilter(Action<IFluentFilterExpression> definition);154155        /**156         * <summary>157         * Adds an order expression to your query.158         * </summary>159         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>160         */161        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);162    }163164    public interface IFluentQuerySetting<T> where T : Entity165    {166        /**167         * <summary>168         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.169         * </summary>170         * <param name="topCount">Top X count of records to retrieve</param>171         */172        IFluentQuery<T> RecordCount(int? topCount);173174        /**175         * <summary>176         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi177         * </summary>178         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 179         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>180         */181        IFluentQuery<T> DatabaseLock(bool useLock = true);182183        /**184         * <summary>185         * Specifies whether duplicate records in your query will be filtered out or not.186         * </summary>187         * <param name="unique">True for only returning unique records, false otherwise</param>188         */189        IFluentQuery<T> UniqueRecords(bool unique = true);  190 - 25191        public FluentQuery(string entityName, IOrganizationService service) - 25192        { - 25193            _query = new QueryExpression - 25194            { - 25195                EntityName = entityName, - 25196                NoLock = true - 25197            };198 - 25199            _service = service; - 25200        }201202        public IFluentQuery<T> IncludeColumns(params string[] columns) - 9203        { - 9204            _query.ColumnSet.AddColumns(columns);205 - 9206            return this; - 9207        }191        /**192         * <summary>193         * Adds paging info to your query, such as page size, page number or paging cookie.194         * </summary>195         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>196         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>197         */198        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);199200        /**201         * <summary>202         * Specifies whether the total record count of your query results should be retrieved.203         * </summary>204         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>205         */206        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);207    }  208209        public IFluentQuerySetting<T> With210        {211            get - 7212            { - 7213                return this; - 7214            }215        }216217        public IFluentQuery<T> RecordCount(int? topCount) - 1218        { - 1219            _query.TopCount = topCount;220 - 1221            return this; - 1222        }223224        public IFluentQuery<T> DatabaseLock(bool useLock = true) - 1225        { - 1226            _query.NoLock = !useLock;227 - 1228            return this; - 1229        }230231        public List<T> Retrieve() - 2232        { - 4233            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>()) - 2234                .ToList(); - 2235        }209    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity210    {211        private QueryExpression _query;212        private IOrganizationService _service;213 + 29214        public FluentQuery(string entityName, IOrganizationService service) + 29215        { + 29216            _query = new QueryExpression + 29217            { + 29218                EntityName = entityName, + 29219                NoLock = true + 29220            };221 + 29222            _service = service; + 29223        }224225        public IFluentQuery<T> IncludeColumns(params string[] columns) + 9226        { + 9227            _query.ColumnSet.AllColumns = false; + 9228            _query.ColumnSet.AddColumns(columns);229 + 9230            return this; + 9231        }232233        public IFluentQuery<T> IncludeAllColumns() + 1234        { + 1235            _query.ColumnSet.AllColumns = true;  236237        public List<T> RetrieveAll() - 1238        { - 1239            var records = new List<T>();240 - 1241            var previousPageNumber = _query.PageInfo.PageNumber; - 1242            var previousPagingCookie = _query.PageInfo.PagingCookie;243 - 1244            var moreRecords = false; - 1245            var pageNumber = previousPageNumber; - 1246            string pagingCookie = previousPagingCookie; + 1237            return this; + 1238        }239240        public IFluentQuerySetting<T> With241        {242            get + 7243            { + 7244                return this; + 7245            }246        }  247248            do - 1249            { - 1250                _query.PageInfo.PageNumber = pageNumber; - 1251                _query.PageInfo.PagingCookie = pagingCookie;252 - 1253                var response = _service.RetrieveMultiple(_query); - 3254                var result = response.Entities.Select(e => e.ToEntity<T>()) - 1255                    .ToList();256 - 1257                records.AddRange(result);248        public IFluentQuery<T> RecordCount(int? topCount) + 1249        { + 1250            _query.TopCount = topCount;251 + 1252            return this; + 1253        }254255        public IFluentQuery<T> DatabaseLock(bool useLock = true) + 1256        { + 1257            _query.NoLock = !useLock;  258 - 1259                moreRecords = response.MoreRecords; - 1260                pageNumber++; - 1261            } - 1262            while (moreRecords);263 - 1264            _query.PageInfo.PageNumber = previousPageNumber; - 1265            _query.PageInfo.PagingCookie = previousPagingCookie;266 - 1267            return records; - 1268        }269270        public IFluentQuery<T> UniqueRecords(bool unique = true) - 1271        { - 1272            _query.Distinct = true;273 - 1274            return this; - 1275        }276277        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition) - 6278        { - 6279            var link = new FluentLinkEntity();280 - 6281            definition(link);282 - 6283            _query.LinkEntities.Add(link.GetLinkEntity());284 - 6285            return this; - 6286        } + 1259            return this; + 1260        }261262        public List<T> Retrieve() + 3263        { + 6264            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>()) + 3265                .ToList(); + 3266        }267268        public List<T> RetrieveAll() + 1269        { + 1270            var records = new List<T>();271 + 1272            var previousPageNumber = _query.PageInfo.PageNumber; + 1273            var previousPagingCookie = _query.PageInfo.PagingCookie;274 + 1275            var moreRecords = false; + 1276            var pageNumber = previousPageNumber; + 1277            string pagingCookie = previousPagingCookie;278279            do + 1280            { + 1281                _query.PageInfo.PageNumber = pageNumber; + 1282                _query.PageInfo.PagingCookie = pagingCookie;283 + 1284                var response = _service.RetrieveMultiple(_query); + 3285                var result = response.Entities.Select(e => e.ToEntity<T>()) + 1286                    .ToList();  287288        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition) - 4289        { - 4290            var filter = new FluentFilterExpression();291 - 4292            definition(filter);293 - 4294            _query.Criteria = filter.GetFilter();295 - 4296            return this; - 4297        }298299        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition) - 5300        { - 5301            var order = new FluentOrderExpression();302 - 5303            definition(order); + 1288                records.AddRange(result);289 + 1290                moreRecords = response.MoreRecords; + 1291                pageNumber++; + 1292            } + 1293            while (moreRecords);294 + 1295            _query.PageInfo.PageNumber = previousPageNumber; + 1296            _query.PageInfo.PagingCookie = previousPagingCookie;297 + 1298            return records; + 1299        }300301        public IFluentQuery<T> UniqueRecords(bool unique = true) + 1302        { + 1303            _query.Distinct = true;  304 - 5305            _query.Orders.Add(order.GetOrder());306 - 5307            return this; - 5308        }309310        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition) - 3311        { - 3312            var PagingInfo = new FluentPagingInfo(); + 1305            return this; + 1306        }307308        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition) + 6309        { + 6310            var link = new FluentLinkEntity();311 + 6312            definition(link);  313 - 3314            definition(PagingInfo); + 6314            _query.LinkEntities.Add(link.GetLinkEntity());  315 - 3316            _query.PageInfo = PagingInfo.GetPagingInfo();317 - 3318            return this; - 3319        }320321        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true) - 1322        { - 1323            _query.PageInfo.ReturnTotalRecordCount = true; + 6316            return this; + 6317        }318319        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition) + 6320        { + 6321            var filter = new FluentFilterExpression();322 + 6323            definition(filter);  324 - 1325            return this; - 1326        }327328        public QueryExpression Expression329        {330            get - 22331            { - 22332                return _query; - 22333            }334        }335    }336337    public interface IFluentLinkEntity338    {339        /**340         * <summary>341         * Logical name of entity that the link is created from.342         * </summary>343         * <param name="entityName">Entity Logical Name</param>344         */345        IFluentLinkEntity FromEntity(string entityName);346347        /**348         * <summary>349         * Logical name of attribute that the link is created from.350         * </summary>351         * <param name="attributeName">Attribute Logical Name</param>352         */353        IFluentLinkEntity FromAttribute(string attributeName);354355        /**356         * <summary>357         * Logical name of entity that the link is created to.358         * </summary>359         * <param name="entityName">Entity Logical Name</param>360         */361        IFluentLinkEntity ToEntity(string entityName); + 6325            _query.Criteria = filter.GetFilter();326 + 6327            return this; + 6328        }329330        public void AddCondition(Action<IFluentConditionExpression> definition) + 1331        { + 1332            var condition = new FluentConditionExpression();333 + 1334            definition(condition);335 + 1336            _query.Criteria.AddCondition(condition.GetCondition()); + 1337        }338339        public void AddFilter(Action<IFluentFilterExpression> definition) + 2340        { + 2341            var filter = new FluentFilterExpression();342 + 2343            definition(filter);344 + 2345            _query.Criteria.AddFilter(filter.GetFilter()); + 2346        }347348        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition) + 5349        { + 5350            var order = new FluentOrderExpression();351 + 5352            definition(order);353 + 5354            _query.Orders.Add(order.GetOrder());355 + 5356            return this; + 5357        }358359        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition) + 3360        { + 3361            var PagingInfo = new FluentPagingInfo();  362363        /**364         * <summary>365         * Logical name of attribute that the link is created to.366         * </summary>367         * <param name="attributeName">Attribute Logical Name</param>368         */369        IFluentLinkEntity ToAttribute(string attributeName);370371        /**372         * <summary>373         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.374         * </summary>375         * <param name="columns">Params array of your columns.</param>376         */377        IFluentLinkEntity IncludeColumns(params string[] columns);378379        /**380        * <summary>381        * Use this for setting further options of your link.382        * </summary>383        */384        IFluentLinkEntitySetting With { get; } + 3363            definition(PagingInfo);364 + 3365            _query.PageInfo = PagingInfo.GetPagingInfo();366 + 3367            return this; + 3368        }369370        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true) + 1371        { + 1372            _query.PageInfo.ReturnTotalRecordCount = true;373 + 1374            return this; + 1375        }376377        public QueryExpression Expression378        {379            get + 25380            { + 25381                return _query; + 25382            }383        }384    }  385386        /**387         * <summary>388         * Adds a nested link to this link.389         * </summary>390         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>391         */392        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);393394        /**395         * <summary>396         * Adds filter conditions to your link.397         * </summary>398         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>399         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>400         */401        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);402    }386    public interface IFluentLinkEntity387    {388        /**389         * <summary>390         * Logical name of entity that the link is created from.391         * </summary>392         * <param name="entityName">Entity Logical Name</param>393         */394        IFluentLinkEntity FromEntity(string entityName);395396        /**397         * <summary>398         * Logical name of attribute that the link is created from.399         * </summary>400         * <param name="attributeName">Attribute Logical Name</param>401         */402        IFluentLinkEntity FromAttribute(string attributeName);  403404    public interface IFluentLinkEntitySetting405    {406        /**407         * <summary>408         * Sets an alias for the results of this link entity.409         * </summary>410         * <param name="name">Alias to set in results.</param>411         */412        IFluentLinkEntity Alias(string name);413414        /**415         * <summary>Join type of this link.</summary>416         * <param name="joinOperator">Join type to use.</param>404        /**405         * <summary>406         * Logical name of entity that the link is created to.407         * </summary>408         * <param name="entityName">Entity Logical Name</param>409         */410        IFluentLinkEntity ToEntity(string entityName);411412        /**413         * <summary>414         * Logical name of attribute that the link is created to.415         * </summary>416         * <param name="attributeName">Attribute Logical Name</param>  417         */418        IFluentLinkEntity LinkType(JoinOperator joinOperator);419    }420421    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting422    {423        private LinkEntity _linkEntity;424425        public FluentLinkEntity()426        {427            _linkEntity = new LinkEntity428            {429                Columns = new ColumnSet()430            };431        }432433        public IFluentLinkEntitySetting With434        {435            get436            {437                return this;438            }439        }440441        public IFluentLinkEntity Alias(string name)442        {443            _linkEntity.EntityAlias = name;444445            return this;446        }447448        public IFluentLinkEntity FromAttribute(string attributeName)449        {450            _linkEntity.LinkFromAttributeName = attributeName;451452            return this;453        }454455        public IFluentLinkEntity FromEntity(string entityName)456        {457            _linkEntity.LinkFromEntityName = entityName;458459            return this;460        }461462        public IFluentLinkEntity IncludeColumns(params string[] columns)463        {464            _linkEntity.Columns.AddColumns(columns);465466            return this;467        }468469        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)470        {471            var filter = new FluentFilterExpression();472473            definition(filter);474475            _linkEntity.LinkCriteria = filter.GetFilter();476477            return this;478        }479480        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)481        {482            var link = new FluentLinkEntity();483484            definition(link);485486            _linkEntity.LinkEntities.Add(link.GetLinkEntity());487488            return this;489        }490491        public IFluentLinkEntity LinkType(JoinOperator joinOperator)492        {493            _linkEntity.JoinOperator = joinOperator;494495            return this;496        }497498        public IFluentLinkEntity ToAttribute(string attributeName)499        {500            _linkEntity.LinkToAttributeName = attributeName;501502            return this;503        }504505        public IFluentLinkEntity ToEntity(string entityName)506        {507            _linkEntity.LinkToEntityName = entityName;508509            return this;510        }511512        internal LinkEntity GetLinkEntity()513        {514            return _linkEntity;515        }516    }418        IFluentLinkEntity ToAttribute(string attributeName);419420        /**421         * <summary>422         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.423         * </summary>424         * <param name="columns">Params array of your columns.</param>425         */426        IFluentLinkEntity IncludeColumns(params string[] columns);427428        /**429        * <summary>430        * Use this for setting further options of your link.431        * </summary>432        */433        IFluentLinkEntitySetting With { get; }434435        /**436         * <summary>437         * Adds a nested link to this link.438         * </summary>439         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>440         */441        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);442443        /**444         * <summary>445         * Adds filter conditions to your link.446         * </summary>447         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>448         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>449         */450        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);451    }452453    public interface IFluentLinkEntitySetting454    {455        /**456         * <summary>457         * Sets an alias for the results of this link entity.458         * </summary>459         * <param name="name">Alias to set in results.</param>460         */461        IFluentLinkEntity Alias(string name);462463        /**464         * <summary>Join type of this link.</summary>465         * <param name="joinOperator">Join type to use.</param>466         */467        IFluentLinkEntity LinkType(JoinOperator joinOperator);468    }469470    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting471    {472        private LinkEntity _linkEntity;473474        public FluentLinkEntity()475        {476            _linkEntity = new LinkEntity477            {478                Columns = new ColumnSet()479            };480        }481482        public IFluentLinkEntitySetting With483        {484            get485            {486                return this;487            }488        }489490        public IFluentLinkEntity Alias(string name)491        {492            _linkEntity.EntityAlias = name;493494            return this;495        }496497        public IFluentLinkEntity FromAttribute(string attributeName)498        {499            _linkEntity.LinkFromAttributeName = attributeName;500501            return this;502        }503504        public IFluentLinkEntity FromEntity(string entityName)505        {506            _linkEntity.LinkFromEntityName = entityName;507508            return this;509        }510511        public IFluentLinkEntity IncludeColumns(params string[] columns)512        {513            _linkEntity.Columns.AddColumns(columns);514515            return this;516        }  517518    public interface IFluentFilterExpression519    {520        /**521        * <summary>522        * Use this for setting further options of your filter.523        * </summary>524        */525        IFluentFilterExpressionSetting With { get; }526527        /**528        * <summary>529        * Use this for adding a condition on an attribute to your filter.530        * </summary>531        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>532        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>533        */534        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);535536        /**537         * <summary>538         * Adds nested filter conditions to your filter.539         * </summary>540         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>541         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>542         */543        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);544    }545546    public interface IFluentFilterExpressionSetting547    {548        /**549         * <summary>550         * Sets the logical operator for chaining multiple conditions in this filter.551         * </summary>552         */553        IFluentFilterExpression Operator(LogicalOperator filterOperator);554    }555556    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting557    {558        private FilterExpression _filter;559560        public FluentFilterExpression()561        {562            _filter = new FilterExpression();563        }564565        public IFluentFilterExpressionSetting With566        {567            get568            {569                return this;570            }571        }572573        public IFluentFilterExpression Operator(LogicalOperator filterOperator)574        {575            _filter.FilterOperator = filterOperator;576577            return this;578        }579580        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)581        {582            var filter = new FluentFilterExpression();583584            definition(filter);585586            _filter.Filters.Add(filter.GetFilter());587588            return this;589        }590591        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)592        {593            var condition = new FluentConditionExpression();518        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)519        {520            var filter = new FluentFilterExpression();521522            definition(filter);523524            _linkEntity.LinkCriteria = filter.GetFilter();525526            return this;527        }528529        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)530        {531            var link = new FluentLinkEntity();532533            definition(link);534535            _linkEntity.LinkEntities.Add(link.GetLinkEntity());536537            return this;538        }539540        public IFluentLinkEntity LinkType(JoinOperator joinOperator)541        {542            _linkEntity.JoinOperator = joinOperator;543544            return this;545        }546547        public IFluentLinkEntity ToAttribute(string attributeName)548        {549            _linkEntity.LinkToAttributeName = attributeName;550551            return this;552        }553554        public IFluentLinkEntity ToEntity(string entityName)555        {556            _linkEntity.LinkToEntityName = entityName;557558            return this;559        }560561        internal LinkEntity GetLinkEntity()562        {563            return _linkEntity;564        }565    }566567    public interface IFluentFilterExpression568    {569        /**570        * <summary>571        * Use this for setting further options of your filter.572        * </summary>573        */574        IFluentFilterExpressionSetting With { get; }575576        /**577        * <summary>578        * Use this for adding a condition on an attribute to your filter.579        * </summary>580        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>581        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>582        */583        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);584585        /**586         * <summary>587         * Adds nested filter conditions to your filter.588         * </summary>589         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>590         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>591         */592        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);593    }  594595            definition(condition);596597            _filter.Conditions.Add(condition.GetCondition());598599            return this;600        }601602        internal FilterExpression GetFilter()603        {604            return _filter;605        }606    }607608    public interface IFluentConditionExpression609    {610        /**611         * <summary>612         * Set the entity name that your condition attribute targets, if it is not the main entity.613         * </summary>614         * <param name="entityName">Entity Logical Name</param>615         */616        IFluentConditionExpression Of(string entityName);617618        /**619         * <summary>620         * Set the logical name of the attribute that your condition targets.621         * </summary>622         * <param name="attributeName">Attribute logical name</param>623         */624        IFluentConditionExpression Named(string attributeName);595    public interface IFluentFilterExpressionSetting596    {597        /**598         * <summary>599         * Sets the logical operator for chaining multiple conditions in this filter.600         * </summary>601         */602        IFluentFilterExpression Operator(LogicalOperator filterOperator);603    }604605    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting606    {607        private FilterExpression _filter;608609        public FluentFilterExpression()610        {611            _filter = new FilterExpression();612        }613614        public IFluentFilterExpressionSetting With615        {616            get617            {618                return this;619            }620        }621622        public IFluentFilterExpression Operator(LogicalOperator filterOperator)623        {624            _filter.FilterOperator = filterOperator;  625626        /**627         * <summary>628         * Set the condition operator for your condition.629         * </summary>630         * <param name="conditionOperator">Condition Operator Enum</param>631         */632        IFluentConditionExpression Is(ConditionOperator conditionOperator);633634        /**635         * <summary>636         * Sets the value for the condition.637         * </summary>638         * <param name="value">Single object, use object array overload if necessary.</param>639         */640        IFluentConditionExpression Value(object value);641642        /**643         * <summary>644         * Sets the values for the condition.645         * </summary>646         * <param name="value">Object array, use object overload if necessary.</param>647         */648        IFluentConditionExpression Value(params object[] value);649650        /**651         * <summary>652         * Alias for Value, provides better readability on Equal conditions.653         * Sets the value for the condition.654         * </summary>655         * <param name="value">Single object, use object array overload if necessary.</param>656         */657        IFluentConditionExpression To(object value);658626            return this;627        }628629        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)630        {631            var filter = new FluentFilterExpression();632633            definition(filter);634635            _filter.Filters.Add(filter.GetFilter());636637            return this;638        }639640        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)641        {642            var condition = new FluentConditionExpression();643644            definition(condition);645646            _filter.Conditions.Add(condition.GetCondition());647648            return this;649        }650651        internal FilterExpression GetFilter()652        {653            return _filter;654        }655    }656657    public interface IFluentConditionExpression658    {  659        /**  660         * <summary>661         * Alias for Value, provides better readability on Equal conditions.662         * Sets the values for the condition.663         * </summary>664         * <param name="value">Object array, use object overload if necessary.</param>665         */666        IFluentConditionExpression To(params object[] value);667    }668669    public class FluentConditionExpression : IFluentConditionExpression670    {671        private ConditionExpression _condition;672673        public FluentConditionExpression()674        {675            _condition = new ConditionExpression();676        }677678        public IFluentConditionExpression Is(ConditionOperator conditionOperator)679        {680            _condition.Operator = conditionOperator;681682            return this;683        }684685        public IFluentConditionExpression Named(string attributeName)686        {687            _condition.AttributeName = attributeName;688689            return this;690        }691692        public IFluentConditionExpression Of(string entityName)693        {694            _condition.EntityName = entityName;695696            return this;697        }661         * Set the entity name that your condition attribute targets, if it is not the main entity.662         * </summary>663         * <param name="entityName">Entity Logical Name</param>664         */665        IFluentConditionExpression Of(string entityName);666667        /**668         * <summary>669         * Set the logical name of the attribute that your condition targets.670         * </summary>671         * <param name="attributeName">Attribute logical name</param>672         */673        IFluentConditionExpression Named(string attributeName);674675        /**676         * <summary>677         * Set the condition operator for your condition.678         * </summary>679         * <param name="conditionOperator">Condition Operator Enum</param>680         */681        IFluentConditionExpression Is(ConditionOperator conditionOperator);682683        /**684         * <summary>685         * Sets the value for the condition.686         * </summary>687         * <param name="value">Single object, use object array overload if necessary.</param>688         */689        IFluentConditionExpression Value(object value);690691        /**692         * <summary>693         * Sets the values for the condition.694         * </summary>695         * <param name="value">Object array, use object overload if necessary.</param>696         */697        IFluentConditionExpression Value(params object[] value);  698699        public IFluentConditionExpression To(object value)700        {701            return Value(value);702        }703704        public IFluentConditionExpression To(params object[] value)705        {706            return Value(value);707        }708709        public IFluentConditionExpression Value(object value)710        {711            _condition.Values.Add(value);712713            return this;714        }715716        public IFluentConditionExpression Value(params object[] value)717        {718            _condition.Values.AddRange(value);719720            return this;721        }722723        internal ConditionExpression GetCondition ()724        {725            return _condition;726        }727    }728729    public interface IFluentOrderExpression730    {731        /**732         * <summary>733         * Set the attribute name to order by.734         * </summary>735         * <param name="attributeName">Attribute logical name</param>736         */737        IFluentOrderExpression By(string attributeName);738739        /**740         * <summary>741         * Sets the sort order to be ascending.742         * </summary>743         */744        IFluentOrderExpression Ascending();745746        /**747         * <summary>748         * Sets the sort order to be descending.749         * </summary>750         */751        IFluentOrderExpression Descending();752    }753754    public class FluentOrderExpression : IFluentOrderExpression755    {756        private OrderExpression _order;699        /**700         * <summary>701         * Alias for Value, provides better readability on Equal conditions.702         * Sets the value for the condition.703         * </summary>704         * <param name="value">Single object, use object array overload if necessary.</param>705         */706        IFluentConditionExpression To(object value);707708        /**709         * <summary>710         * Alias for Value, provides better readability on Equal conditions.711         * Sets the values for the condition.712         * </summary>713         * <param name="value">Object array, use object overload if necessary.</param>714         */715        IFluentConditionExpression To(params object[] value);716    }717718    public class FluentConditionExpression : IFluentConditionExpression719    {720        private ConditionExpression _condition;721722        public FluentConditionExpression()723        {724            _condition = new ConditionExpression();725        }726727        public IFluentConditionExpression Is(ConditionOperator conditionOperator)728        {729            _condition.Operator = conditionOperator;730731            return this;732        }733734        public IFluentConditionExpression Named(string attributeName)735        {736            _condition.AttributeName = attributeName;737738            return this;739        }740741        public IFluentConditionExpression Of(string entityName)742        {743            _condition.EntityName = entityName;744745            return this;746        }747748        public IFluentConditionExpression To(object value)749        {750            return Value(value);751        }752753        public IFluentConditionExpression To(params object[] value)754        {755            return Value(value);756        }  757758        public FluentOrderExpression ()758        public IFluentConditionExpression Value(object value)  759        {760            _order = new OrderExpression();761        }762763        public IFluentOrderExpression By(string attributeName)764        {765            _order.AttributeName = attributeName;766767            return this;768        }769770        public IFluentOrderExpression Ascending()771        {772            _order.OrderType = OrderType.Ascending;773774            return this;760            _condition.Values.Add(value);761762            return this;763        }764765        public IFluentConditionExpression Value(params object[] value)766        {767            _condition.Values.AddRange(value);768769            return this;770        }771772        internal ConditionExpression GetCondition ()773        {774            return _condition;  775        }776777        public IFluentOrderExpression Descending()778        {779            _order.OrderType = OrderType.Descending;780781            return this;782        }783784        internal OrderExpression GetOrder()785        {786            return _order;787        }788    }789790    public interface IFluentPagingInfo791    {792        /**793         * <summary>794         * Set the page number to retrieve. Is set to 1 by default.795         * </summary>796         * <param name="number">Number of the page, starts at 1.</param>797         */798        IFluentPagingInfo PageNumber(int number);799800        /**801         * <summary>802         * Set the paging cookie for retrieving records from pages after the first.803         * </summary>804         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>805         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>806         */807        IFluentPagingInfo PagingCookie(string pagingCookie);808809        /**810         * <summary>811         * Set the size of each page.812         * </summary>813         * <param name="number">Number of records to return per page.</param>814         */815        IFluentPagingInfo PageSize(int number);816817        /**818         * <summary>819         * Specifies whether the total record count of your query results should be retrieved.820         * </summary>821         * <param name="returnTotal">True for returning total record count, false otherwise.</param>822         */823        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);824    }776    }777778    public interface IFluentOrderExpression779    {780        /**781         * <summary>782         * Set the attribute name to order by.783         * </summary>784         * <param name="attributeName">Attribute logical name</param>785         */786        IFluentOrderExpression By(string attributeName);787788        /**789         * <summary>790         * Sets the sort order to be ascending.791         * </summary>792         */793        IFluentOrderExpression Ascending();794795        /**796         * <summary>797         * Sets the sort order to be descending.798         * </summary>799         */800        IFluentOrderExpression Descending();801    }802803    public class FluentOrderExpression : IFluentOrderExpression804    {805        private OrderExpression _order;806807        public FluentOrderExpression ()808        {809            _order = new OrderExpression();810        }811812        public IFluentOrderExpression By(string attributeName)813        {814            _order.AttributeName = attributeName;815816            return this;817        }818819        public IFluentOrderExpression Ascending()820        {821            _order.OrderType = OrderType.Ascending;822823            return this;824        }  825826    public class FluentPagingInfo : IFluentPagingInfo827    {828        private PagingInfo _pagingInfo;826        public IFluentOrderExpression Descending()827        {828            _order.OrderType = OrderType.Descending;  829830        public FluentPagingInfo()831        {832            _pagingInfo = new PagingInfo833            {834                PageNumber = 1835            };830            return this;831        }832833        internal OrderExpression GetOrder()834        {835            return _order;  836        }837838        public IFluentPagingInfo PageNumber(int number)839        {840            _pagingInfo.PageNumber = number;841842            return this;843        }844845        public IFluentPagingInfo PageSize(int number)846        {847            _pagingInfo.Count = number;837    }838839    public interface IFluentPagingInfo840    {841        /**842         * <summary>843         * Set the page number to retrieve. Is set to 1 by default.844         * </summary>845         * <param name="number">Number of the page, starts at 1.</param>846         */847        IFluentPagingInfo PageNumber(int number);  848849            return this;850        }851852        public IFluentPagingInfo PagingCookie(string pagingCookie)853        {854            _pagingInfo.PagingCookie = pagingCookie;855856            return this;857        }858859        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)860        {861            _pagingInfo.ReturnTotalRecordCount = returnTotal;862863            return this;864        }849        /**850         * <summary>851         * Set the paging cookie for retrieving records from pages after the first.852         * </summary>853         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>854         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>855         */856        IFluentPagingInfo PagingCookie(string pagingCookie);857858        /**859         * <summary>860         * Set the size of each page.861         * </summary>862         * <param name="number">Number of records to return per page.</param>863         */864        IFluentPagingInfo PageSize(int number);  865866        public PagingInfo GetPagingInfo()867        {868            return _pagingInfo;869        }870    }871}866        /**867         * <summary>868         * Specifies whether the total record count of your query results should be retrieved.869         * </summary>870         * <param name="returnTotal">True for returning total record count, false otherwise.</param>871         */872        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);873    }874875    public class FluentPagingInfo : IFluentPagingInfo876    {877        private PagingInfo _pagingInfo;878879        public FluentPagingInfo()880        {881            _pagingInfo = new PagingInfo882            {883                PageNumber = 1884            };885        }886887        public IFluentPagingInfo PageNumber(int number)888        {889            _pagingInfo.PageNumber = number;890891            return this;892        }893894        public IFluentPagingInfo PageSize(int number)895        {896            _pagingInfo.Count = number;897898            return this;899        }900901        public IFluentPagingInfo PagingCookie(string pagingCookie)902        {903            _pagingInfo.PagingCookie = pagingCookie;904905            return this;906        }907908        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)909        {910            _pagingInfo.ReturnTotalRecordCount = returnTotal;911912            return this;913        }914915        public PagingInfo GetPagingInfo()916        {917            return _pagingInfo;918        }919    }920} - + diff --git a/reports/Xrm.Oss.FluentQuery_IOrganizationServiceFluentQuery.htm b/reports/Xrm.Oss.FluentQuery_IOrganizationServiceFluentQuery.htm index 29e1ef6..46f3b5d 100644 --- a/reports/Xrm.Oss.FluentQuery_IOrganizationServiceFluentQuery.htm +++ b/reports/Xrm.Oss.FluentQuery_IOrganizationServiceFluentQuery.htm @@ -20,7 +20,7 @@

Summary

Covered lines:9 Uncovered lines:0 Coverable lines:9 -Total lines:871 +Total lines:920 Line coverage:100% @@ -107,9 +107,9 @@

 67         * <returns>Fluent Query object. Use Retrieve or RetrieveAll for getting the results.</returns>  68         */  69        public static IFluentQuery<Entity> Query(this IOrganizationService service, string entityName) - 2370        { - 2371            return new FluentQuery<Entity>(entityName, service); - 2372        } + 2770        { + 2771            return new FluentQuery<Entity>(entityName, service); + 2772        }  73    }  74  75    public interface IFluentQuery<T> where T : Entity @@ -124,794 +124,843 @@

 84  85        /**  86         * <summary>87         * Returns the Query Expression that represents the current fluent query.87         * Adds all columns to the query. This is disadvised, specify the columns you need if possible.  88         * </summary>  89         */90        QueryExpression Expression { get; }90        IFluentQuery<T> IncludeAllColumns();  91  92        /**  93         * <summary>94         * Retrieves the first page for your query.94         * Returns the Query Expression that represents the current fluent query.  95         * </summary>96         * <returns>Records retrieved from your query.</returns>97         */98        List<T> Retrieve();99100        /**101         * <summary>102         * Retrieves all pages for your query.103         * </summary>104         * <returns>Records retrieved from your query.</returns>105         */106        List<T> RetrieveAll();107108        /**109         * <summary>110         * Use this for setting further options in your query.111         * </summary>96         */97        QueryExpression Expression { get; }9899        /**100         * <summary>101         * Retrieves the first page for your query.102         * </summary>103         * <returns>Records retrieved from your query.</returns>104         */105        List<T> Retrieve();106107        /**108         * <summary>109         * Retrieves all pages for your query.110         * </summary>111         * <returns>Records retrieved from your query.</returns>  112         */113        IFluentQuerySetting<T> With { get; }113        List<T> RetrieveAll();  114  115        /**  116         * <summary>117         * Adds a link to a connected entity.117         * Use this for setting further options in your query.  118         * </summary>119         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>120         */121        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);122123        /**124         * <summary>125         * Adds filter conditions to your query.126         * </summary>127         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>128         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>129         */130        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);131132        /**133         * <summary>134         * Adds an order expression to your query.135         * </summary>136         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>137         */138        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);139    }140141    public interface IFluentQuerySetting<T> where T : Entity142    {143        /**144         * <summary>145         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.146         * </summary>147         * <param name="topCount">Top X count of records to retrieve</param>148         */149        IFluentQuery<T> RecordCount(int? topCount);150151        /**152         * <summary>153         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi154         * </summary>155         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 156         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>157         */158        IFluentQuery<T> DatabaseLock(bool useLock = true);159160        /**161         * <summary>162         * Specifies whether duplicate records in your query will be filtered out or not.163         * </summary>164         * <param name="unique">True for only returning unique records, false otherwise</param>165         */166        IFluentQuery<T> UniqueRecords(bool unique = true);167168        /**169         * <summary>170         * Adds paging info to your query, such as page size, page number or paging cookie.171         * </summary>172         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>173         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>174         */175        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);176177        /**178         * <summary>179         * Specifies whether the total record count of your query results should be retrieved.180         * </summary>181         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>182         */183        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);184    }185186    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity187    {188        private QueryExpression _query;189        private IOrganizationService _service;119         */120        IFluentQuerySetting<T> With { get; }121122        /**123         * <summary>124         * Adds a link to a connected entity.125         * </summary>126         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>127         */128        IFluentQuery<T> Link(Action<IFluentLinkEntity> definition);129130        /**131         * <summary>132         * Adds filter conditions to your query.133         * </summary>134         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>135         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>136         */137        IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);138139        /**140         * <summary>141         * Adds another condition to the top level filter expression.142         * </summary>143         * <param name="definition">The condition expression to add.</param>144         */145        void AddCondition(Action<IFluentConditionExpression> definition);146147        /**148         * <summary>149         * Adds a child filter to your top level filter.150         * </summary>151         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>152         */153        void AddFilter(Action<IFluentFilterExpression> definition);154155        /**156         * <summary>157         * Adds an order expression to your query.158         * </summary>159         * <param name="definition">Action for setting the order properties. Use a lambda for readability.</param>160         */161        IFluentQuery<T> Order(Action<IFluentOrderExpression> definition);162    }163164    public interface IFluentQuerySetting<T> where T : Entity165    {166        /**167         * <summary>168         * Set this for defining how many records you want to retrieve. The first top X records will be retrieved.169         * </summary>170         * <param name="topCount">Top X count of records to retrieve</param>171         */172        IFluentQuery<T> RecordCount(int? topCount);173174        /**175         * <summary>176         * Defines whether the record should be locked for retrieval. Not locking is a recommended best practice, but mi177         * </summary>178         * <remarks>Default of true is recommended as best practice. Dirty reads might occur if data is written to this 179         * <param name="useLock">True for locking the database record for retrieval, false otherwise.</param>180         */181        IFluentQuery<T> DatabaseLock(bool useLock = true);182183        /**184         * <summary>185         * Specifies whether duplicate records in your query will be filtered out or not.186         * </summary>187         * <param name="unique">True for only returning unique records, false otherwise</param>188         */189        IFluentQuery<T> UniqueRecords(bool unique = true);  190191        public FluentQuery(string entityName, IOrganizationService service)192        {193            _query = new QueryExpression194            {195                EntityName = entityName,196                NoLock = true197            };198199            _service = service;200        }201202        public IFluentQuery<T> IncludeColumns(params string[] columns)203        {204            _query.ColumnSet.AddColumns(columns);205206            return this;207        }191        /**192         * <summary>193         * Adds paging info to your query, such as page size, page number or paging cookie.194         * </summary>195         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>196         * <param name="definition">Action for setting the paging info properties. Use a lambda for readability.</param>197         */198        IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition);199200        /**201         * <summary>202         * Specifies whether the total record count of your query results should be retrieved.203         * </summary>204         * <param name="returnTotalRecordCount">True for returning total record count, false otherwise.</param>205         */206        IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true);207    }  208209        public IFluentQuerySetting<T> With210        {211            get212            {213                return this;214            }215        }216217        public IFluentQuery<T> RecordCount(int? topCount)218        {219            _query.TopCount = topCount;220221            return this;222        }223224        public IFluentQuery<T> DatabaseLock(bool useLock = true)225        {226            _query.NoLock = !useLock;227228            return this;229        }230231        public List<T> Retrieve()232        {233            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())234                .ToList();235        }209    public class FluentQuery<T> : IFluentQuery<T>, IFluentQuerySetting<T> where T : Entity210    {211        private QueryExpression _query;212        private IOrganizationService _service;213214        public FluentQuery(string entityName, IOrganizationService service)215        {216            _query = new QueryExpression217            {218                EntityName = entityName,219                NoLock = true220            };221222            _service = service;223        }224225        public IFluentQuery<T> IncludeColumns(params string[] columns)226        {227            _query.ColumnSet.AllColumns = false;228            _query.ColumnSet.AddColumns(columns);229230            return this;231        }232233        public IFluentQuery<T> IncludeAllColumns()234        {235            _query.ColumnSet.AllColumns = true;  236237        public List<T> RetrieveAll()238        {239            var records = new List<T>();240241            var previousPageNumber = _query.PageInfo.PageNumber;242            var previousPagingCookie = _query.PageInfo.PagingCookie;243244            var moreRecords = false;245            var pageNumber = previousPageNumber;246            string pagingCookie = previousPagingCookie;237            return this;238        }239240        public IFluentQuerySetting<T> With241        {242            get243            {244                return this;245            }246        }  247248            do249            {250                _query.PageInfo.PageNumber = pageNumber;251                _query.PageInfo.PagingCookie = pagingCookie;252253                var response = _service.RetrieveMultiple(_query);254                var result = response.Entities.Select(e => e.ToEntity<T>())255                    .ToList();256257                records.AddRange(result);248        public IFluentQuery<T> RecordCount(int? topCount)249        {250            _query.TopCount = topCount;251252            return this;253        }254255        public IFluentQuery<T> DatabaseLock(bool useLock = true)256        {257            _query.NoLock = !useLock;  258259                moreRecords = response.MoreRecords;260                pageNumber++;261            }262            while (moreRecords);263264            _query.PageInfo.PageNumber = previousPageNumber;265            _query.PageInfo.PagingCookie = previousPagingCookie;266267            return records;268        }269270        public IFluentQuery<T> UniqueRecords(bool unique = true)271        {272            _query.Distinct = true;273274            return this;275        }276277        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)278        {279            var link = new FluentLinkEntity();280281            definition(link);282283            _query.LinkEntities.Add(link.GetLinkEntity());284285            return this;286        }259            return this;260        }261262        public List<T> Retrieve()263        {264            return _service.RetrieveMultiple(_query).Entities.Select(e => e.ToEntity<T>())265                .ToList();266        }267268        public List<T> RetrieveAll()269        {270            var records = new List<T>();271272            var previousPageNumber = _query.PageInfo.PageNumber;273            var previousPagingCookie = _query.PageInfo.PagingCookie;274275            var moreRecords = false;276            var pageNumber = previousPageNumber;277            string pagingCookie = previousPagingCookie;278279            do280            {281                _query.PageInfo.PageNumber = pageNumber;282                _query.PageInfo.PagingCookie = pagingCookie;283284                var response = _service.RetrieveMultiple(_query);285                var result = response.Entities.Select(e => e.ToEntity<T>())286                    .ToList();  287288        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)289        {290            var filter = new FluentFilterExpression();291292            definition(filter);293294            _query.Criteria = filter.GetFilter();295296            return this;297        }298299        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)300        {301            var order = new FluentOrderExpression();302303            definition(order);288                records.AddRange(result);289290                moreRecords = response.MoreRecords;291                pageNumber++;292            }293            while (moreRecords);294295            _query.PageInfo.PageNumber = previousPageNumber;296            _query.PageInfo.PagingCookie = previousPagingCookie;297298            return records;299        }300301        public IFluentQuery<T> UniqueRecords(bool unique = true)302        {303            _query.Distinct = true;  304305            _query.Orders.Add(order.GetOrder());306307            return this;308        }309310        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)311        {312            var PagingInfo = new FluentPagingInfo();305            return this;306        }307308        public IFluentQuery<T> Link(Action<IFluentLinkEntity> definition)309        {310            var link = new FluentLinkEntity();311312            definition(link);  313314            definition(PagingInfo);314            _query.LinkEntities.Add(link.GetLinkEntity());  315316            _query.PageInfo = PagingInfo.GetPagingInfo();317318            return this;319        }320321        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)322        {323            _query.PageInfo.ReturnTotalRecordCount = true;316            return this;317        }318319        public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)320        {321            var filter = new FluentFilterExpression();322323            definition(filter);  324325            return this;326        }327328        public QueryExpression Expression329        {330            get331            {332                return _query;333            }334        }335    }336337    public interface IFluentLinkEntity338    {339        /**340         * <summary>341         * Logical name of entity that the link is created from.342         * </summary>343         * <param name="entityName">Entity Logical Name</param>344         */345        IFluentLinkEntity FromEntity(string entityName);346347        /**348         * <summary>349         * Logical name of attribute that the link is created from.350         * </summary>351         * <param name="attributeName">Attribute Logical Name</param>352         */353        IFluentLinkEntity FromAttribute(string attributeName);354355        /**356         * <summary>357         * Logical name of entity that the link is created to.358         * </summary>359         * <param name="entityName">Entity Logical Name</param>360         */361        IFluentLinkEntity ToEntity(string entityName);325            _query.Criteria = filter.GetFilter();326327            return this;328        }329330        public void AddCondition(Action<IFluentConditionExpression> definition)331        {332            var condition = new FluentConditionExpression();333334            definition(condition);335336            _query.Criteria.AddCondition(condition.GetCondition());337        }338339        public void AddFilter(Action<IFluentFilterExpression> definition)340        {341            var filter = new FluentFilterExpression();342343            definition(filter);344345            _query.Criteria.AddFilter(filter.GetFilter());346        }347348        public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)349        {350            var order = new FluentOrderExpression();351352            definition(order);353354            _query.Orders.Add(order.GetOrder());355356            return this;357        }358359        public IFluentQuery<T> PagingInfo(Action<IFluentPagingInfo> definition)360        {361            var PagingInfo = new FluentPagingInfo();  362363        /**364         * <summary>365         * Logical name of attribute that the link is created to.366         * </summary>367         * <param name="attributeName">Attribute Logical Name</param>368         */369        IFluentLinkEntity ToAttribute(string attributeName);370371        /**372         * <summary>373         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.374         * </summary>375         * <param name="columns">Params array of your columns.</param>376         */377        IFluentLinkEntity IncludeColumns(params string[] columns);378379        /**380        * <summary>381        * Use this for setting further options of your link.382        * </summary>383        */384        IFluentLinkEntitySetting With { get; }363            definition(PagingInfo);364365            _query.PageInfo = PagingInfo.GetPagingInfo();366367            return this;368        }369370        public IFluentQuery<T> TotalRecordCount(bool returnTotalRecordCount = true)371        {372            _query.PageInfo.ReturnTotalRecordCount = true;373374            return this;375        }376377        public QueryExpression Expression378        {379            get380            {381                return _query;382            }383        }384    }  385386        /**387         * <summary>388         * Adds a nested link to this link.389         * </summary>390         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>391         */392        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);393394        /**395         * <summary>396         * Adds filter conditions to your link.397         * </summary>398         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>399         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>400         */401        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);402    }386    public interface IFluentLinkEntity387    {388        /**389         * <summary>390         * Logical name of entity that the link is created from.391         * </summary>392         * <param name="entityName">Entity Logical Name</param>393         */394        IFluentLinkEntity FromEntity(string entityName);395396        /**397         * <summary>398         * Logical name of attribute that the link is created from.399         * </summary>400         * <param name="attributeName">Attribute Logical Name</param>401         */402        IFluentLinkEntity FromAttribute(string attributeName);  403404    public interface IFluentLinkEntitySetting405    {406        /**407         * <summary>408         * Sets an alias for the results of this link entity.409         * </summary>410         * <param name="name">Alias to set in results.</param>411         */412        IFluentLinkEntity Alias(string name);413414        /**415         * <summary>Join type of this link.</summary>416         * <param name="joinOperator">Join type to use.</param>404        /**405         * <summary>406         * Logical name of entity that the link is created to.407         * </summary>408         * <param name="entityName">Entity Logical Name</param>409         */410        IFluentLinkEntity ToEntity(string entityName);411412        /**413         * <summary>414         * Logical name of attribute that the link is created to.415         * </summary>416         * <param name="attributeName">Attribute Logical Name</param>  417         */418        IFluentLinkEntity LinkType(JoinOperator joinOperator);419    }420421    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting422    {423        private LinkEntity _linkEntity;424425        public FluentLinkEntity()426        {427            _linkEntity = new LinkEntity428            {429                Columns = new ColumnSet()430            };431        }432433        public IFluentLinkEntitySetting With434        {435            get436            {437                return this;438            }439        }440441        public IFluentLinkEntity Alias(string name)442        {443            _linkEntity.EntityAlias = name;444445            return this;446        }447448        public IFluentLinkEntity FromAttribute(string attributeName)449        {450            _linkEntity.LinkFromAttributeName = attributeName;451452            return this;453        }454455        public IFluentLinkEntity FromEntity(string entityName)456        {457            _linkEntity.LinkFromEntityName = entityName;458459            return this;460        }461462        public IFluentLinkEntity IncludeColumns(params string[] columns)463        {464            _linkEntity.Columns.AddColumns(columns);465466            return this;467        }468469        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)470        {471            var filter = new FluentFilterExpression();472473            definition(filter);474475            _linkEntity.LinkCriteria = filter.GetFilter();476477            return this;478        }479480        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)481        {482            var link = new FluentLinkEntity();483484            definition(link);485486            _linkEntity.LinkEntities.Add(link.GetLinkEntity());487488            return this;489        }490491        public IFluentLinkEntity LinkType(JoinOperator joinOperator)492        {493            _linkEntity.JoinOperator = joinOperator;494495            return this;496        }497498        public IFluentLinkEntity ToAttribute(string attributeName)499        {500            _linkEntity.LinkToAttributeName = attributeName;501502            return this;503        }504505        public IFluentLinkEntity ToEntity(string entityName)506        {507            _linkEntity.LinkToEntityName = entityName;508509            return this;510        }511512        internal LinkEntity GetLinkEntity()513        {514            return _linkEntity;515        }516    }418        IFluentLinkEntity ToAttribute(string attributeName);419420        /**421         * <summary>422         * Adds the given columns to the link entity. Multiple calls will just add to the existing columns.423         * </summary>424         * <param name="columns">Params array of your columns.</param>425         */426        IFluentLinkEntity IncludeColumns(params string[] columns);427428        /**429        * <summary>430        * Use this for setting further options of your link.431        * </summary>432        */433        IFluentLinkEntitySetting With { get; }434435        /**436         * <summary>437         * Adds a nested link to this link.438         * </summary>439         * <param name="definition">Action for setting the link properties. Use a lambda for readability.</param>440         */441        IFluentLinkEntity Link(Action<IFluentLinkEntity> definition);442443        /**444         * <summary>445         * Adds filter conditions to your link.446         * </summary>447         * <remarks>Multiple calls to this method currently override the existing filter.</remarks>448         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>449         */450        IFluentLinkEntity Where(Action<IFluentFilterExpression> definition);451    }452453    public interface IFluentLinkEntitySetting454    {455        /**456         * <summary>457         * Sets an alias for the results of this link entity.458         * </summary>459         * <param name="name">Alias to set in results.</param>460         */461        IFluentLinkEntity Alias(string name);462463        /**464         * <summary>Join type of this link.</summary>465         * <param name="joinOperator">Join type to use.</param>466         */467        IFluentLinkEntity LinkType(JoinOperator joinOperator);468    }469470    public class FluentLinkEntity : IFluentLinkEntity, IFluentLinkEntitySetting471    {472        private LinkEntity _linkEntity;473474        public FluentLinkEntity()475        {476            _linkEntity = new LinkEntity477            {478                Columns = new ColumnSet()479            };480        }481482        public IFluentLinkEntitySetting With483        {484            get485            {486                return this;487            }488        }489490        public IFluentLinkEntity Alias(string name)491        {492            _linkEntity.EntityAlias = name;493494            return this;495        }496497        public IFluentLinkEntity FromAttribute(string attributeName)498        {499            _linkEntity.LinkFromAttributeName = attributeName;500501            return this;502        }503504        public IFluentLinkEntity FromEntity(string entityName)505        {506            _linkEntity.LinkFromEntityName = entityName;507508            return this;509        }510511        public IFluentLinkEntity IncludeColumns(params string[] columns)512        {513            _linkEntity.Columns.AddColumns(columns);514515            return this;516        }  517518    public interface IFluentFilterExpression519    {520        /**521        * <summary>522        * Use this for setting further options of your filter.523        * </summary>524        */525        IFluentFilterExpressionSetting With { get; }526527        /**528        * <summary>529        * Use this for adding a condition on an attribute to your filter.530        * </summary>531        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>532        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>533        */534        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);535536        /**537         * <summary>538         * Adds nested filter conditions to your filter.539         * </summary>540         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>541         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>542         */543        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);544    }545546    public interface IFluentFilterExpressionSetting547    {548        /**549         * <summary>550         * Sets the logical operator for chaining multiple conditions in this filter.551         * </summary>552         */553        IFluentFilterExpression Operator(LogicalOperator filterOperator);554    }555556    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting557    {558        private FilterExpression _filter;559560        public FluentFilterExpression()561        {562            _filter = new FilterExpression();563        }564565        public IFluentFilterExpressionSetting With566        {567            get568            {569                return this;570            }571        }572573        public IFluentFilterExpression Operator(LogicalOperator filterOperator)574        {575            _filter.FilterOperator = filterOperator;576577            return this;578        }579580        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)581        {582            var filter = new FluentFilterExpression();583584            definition(filter);585586            _filter.Filters.Add(filter.GetFilter());587588            return this;589        }590591        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)592        {593            var condition = new FluentConditionExpression();518        public IFluentLinkEntity Where(Action<IFluentFilterExpression> definition)519        {520            var filter = new FluentFilterExpression();521522            definition(filter);523524            _linkEntity.LinkCriteria = filter.GetFilter();525526            return this;527        }528529        public IFluentLinkEntity Link(Action<IFluentLinkEntity> definition)530        {531            var link = new FluentLinkEntity();532533            definition(link);534535            _linkEntity.LinkEntities.Add(link.GetLinkEntity());536537            return this;538        }539540        public IFluentLinkEntity LinkType(JoinOperator joinOperator)541        {542            _linkEntity.JoinOperator = joinOperator;543544            return this;545        }546547        public IFluentLinkEntity ToAttribute(string attributeName)548        {549            _linkEntity.LinkToAttributeName = attributeName;550551            return this;552        }553554        public IFluentLinkEntity ToEntity(string entityName)555        {556            _linkEntity.LinkToEntityName = entityName;557558            return this;559        }560561        internal LinkEntity GetLinkEntity()562        {563            return _linkEntity;564        }565    }566567    public interface IFluentFilterExpression568    {569        /**570        * <summary>571        * Use this for setting further options of your filter.572        * </summary>573        */574        IFluentFilterExpressionSetting With { get; }575576        /**577        * <summary>578        * Use this for adding a condition on an attribute to your filter.579        * </summary>580        * <remarks>Multiple calls to Attribute will add to the existing ones.</remarks>581        * <param name="definition">Action for setting the attribute properties. Use a lambda for readability.</param>582        */583        IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition);584585        /**586         * <summary>587         * Adds nested filter conditions to your filter.588         * </summary>589         * <remarks>Multiple calls to this method add to the existing filter conditions.</remarks>590         * <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>591         */592        IFluentFilterExpression Where(Action<IFluentFilterExpression> definition);593    }  594595            definition(condition);596597            _filter.Conditions.Add(condition.GetCondition());598599            return this;600        }601602        internal FilterExpression GetFilter()603        {604            return _filter;605        }606    }607608    public interface IFluentConditionExpression609    {610        /**611         * <summary>612         * Set the entity name that your condition attribute targets, if it is not the main entity.613         * </summary>614         * <param name="entityName">Entity Logical Name</param>615         */616        IFluentConditionExpression Of(string entityName);617618        /**619         * <summary>620         * Set the logical name of the attribute that your condition targets.621         * </summary>622         * <param name="attributeName">Attribute logical name</param>623         */624        IFluentConditionExpression Named(string attributeName);595    public interface IFluentFilterExpressionSetting596    {597        /**598         * <summary>599         * Sets the logical operator for chaining multiple conditions in this filter.600         * </summary>601         */602        IFluentFilterExpression Operator(LogicalOperator filterOperator);603    }604605    public class FluentFilterExpression : IFluentFilterExpression, IFluentFilterExpressionSetting606    {607        private FilterExpression _filter;608609        public FluentFilterExpression()610        {611            _filter = new FilterExpression();612        }613614        public IFluentFilterExpressionSetting With615        {616            get617            {618                return this;619            }620        }621622        public IFluentFilterExpression Operator(LogicalOperator filterOperator)623        {624            _filter.FilterOperator = filterOperator;  625626        /**627         * <summary>628         * Set the condition operator for your condition.629         * </summary>630         * <param name="conditionOperator">Condition Operator Enum</param>631         */632        IFluentConditionExpression Is(ConditionOperator conditionOperator);633634        /**635         * <summary>636         * Sets the value for the condition.637         * </summary>638         * <param name="value">Single object, use object array overload if necessary.</param>639         */640        IFluentConditionExpression Value(object value);641642        /**643         * <summary>644         * Sets the values for the condition.645         * </summary>646         * <param name="value">Object array, use object overload if necessary.</param>647         */648        IFluentConditionExpression Value(params object[] value);649650        /**651         * <summary>652         * Alias for Value, provides better readability on Equal conditions.653         * Sets the value for the condition.654         * </summary>655         * <param name="value">Single object, use object array overload if necessary.</param>656         */657        IFluentConditionExpression To(object value);658626            return this;627        }628629        public IFluentFilterExpression Where(Action<IFluentFilterExpression> definition)630        {631            var filter = new FluentFilterExpression();632633            definition(filter);634635            _filter.Filters.Add(filter.GetFilter());636637            return this;638        }639640        public IFluentFilterExpression Attribute(Action<IFluentConditionExpression> definition)641        {642            var condition = new FluentConditionExpression();643644            definition(condition);645646            _filter.Conditions.Add(condition.GetCondition());647648            return this;649        }650651        internal FilterExpression GetFilter()652        {653            return _filter;654        }655    }656657    public interface IFluentConditionExpression658    {  659        /**  660         * <summary>661         * Alias for Value, provides better readability on Equal conditions.662         * Sets the values for the condition.663         * </summary>664         * <param name="value">Object array, use object overload if necessary.</param>665         */666        IFluentConditionExpression To(params object[] value);667    }668669    public class FluentConditionExpression : IFluentConditionExpression670    {671        private ConditionExpression _condition;672673        public FluentConditionExpression()674        {675            _condition = new ConditionExpression();676        }677678        public IFluentConditionExpression Is(ConditionOperator conditionOperator)679        {680            _condition.Operator = conditionOperator;681682            return this;683        }684685        public IFluentConditionExpression Named(string attributeName)686        {687            _condition.AttributeName = attributeName;688689            return this;690        }691692        public IFluentConditionExpression Of(string entityName)693        {694            _condition.EntityName = entityName;695696            return this;697        }661         * Set the entity name that your condition attribute targets, if it is not the main entity.662         * </summary>663         * <param name="entityName">Entity Logical Name</param>664         */665        IFluentConditionExpression Of(string entityName);666667        /**668         * <summary>669         * Set the logical name of the attribute that your condition targets.670         * </summary>671         * <param name="attributeName">Attribute logical name</param>672         */673        IFluentConditionExpression Named(string attributeName);674675        /**676         * <summary>677         * Set the condition operator for your condition.678         * </summary>679         * <param name="conditionOperator">Condition Operator Enum</param>680         */681        IFluentConditionExpression Is(ConditionOperator conditionOperator);682683        /**684         * <summary>685         * Sets the value for the condition.686         * </summary>687         * <param name="value">Single object, use object array overload if necessary.</param>688         */689        IFluentConditionExpression Value(object value);690691        /**692         * <summary>693         * Sets the values for the condition.694         * </summary>695         * <param name="value">Object array, use object overload if necessary.</param>696         */697        IFluentConditionExpression Value(params object[] value);  698699        public IFluentConditionExpression To(object value)700        {701            return Value(value);702        }703704        public IFluentConditionExpression To(params object[] value)705        {706            return Value(value);707        }708709        public IFluentConditionExpression Value(object value)710        {711            _condition.Values.Add(value);712713            return this;714        }715716        public IFluentConditionExpression Value(params object[] value)717        {718            _condition.Values.AddRange(value);719720            return this;721        }722723        internal ConditionExpression GetCondition ()724        {725            return _condition;726        }727    }728729    public interface IFluentOrderExpression730    {731        /**732         * <summary>733         * Set the attribute name to order by.734         * </summary>735         * <param name="attributeName">Attribute logical name</param>736         */737        IFluentOrderExpression By(string attributeName);738739        /**740         * <summary>741         * Sets the sort order to be ascending.742         * </summary>743         */744        IFluentOrderExpression Ascending();745746        /**747         * <summary>748         * Sets the sort order to be descending.749         * </summary>750         */751        IFluentOrderExpression Descending();752    }753754    public class FluentOrderExpression : IFluentOrderExpression755    {756        private OrderExpression _order;699        /**700         * <summary>701         * Alias for Value, provides better readability on Equal conditions.702         * Sets the value for the condition.703         * </summary>704         * <param name="value">Single object, use object array overload if necessary.</param>705         */706        IFluentConditionExpression To(object value);707708        /**709         * <summary>710         * Alias for Value, provides better readability on Equal conditions.711         * Sets the values for the condition.712         * </summary>713         * <param name="value">Object array, use object overload if necessary.</param>714         */715        IFluentConditionExpression To(params object[] value);716    }717718    public class FluentConditionExpression : IFluentConditionExpression719    {720        private ConditionExpression _condition;721722        public FluentConditionExpression()723        {724            _condition = new ConditionExpression();725        }726727        public IFluentConditionExpression Is(ConditionOperator conditionOperator)728        {729            _condition.Operator = conditionOperator;730731            return this;732        }733734        public IFluentConditionExpression Named(string attributeName)735        {736            _condition.AttributeName = attributeName;737738            return this;739        }740741        public IFluentConditionExpression Of(string entityName)742        {743            _condition.EntityName = entityName;744745            return this;746        }747748        public IFluentConditionExpression To(object value)749        {750            return Value(value);751        }752753        public IFluentConditionExpression To(params object[] value)754        {755            return Value(value);756        }  757758        public FluentOrderExpression ()758        public IFluentConditionExpression Value(object value)  759        {760            _order = new OrderExpression();761        }762763        public IFluentOrderExpression By(string attributeName)764        {765            _order.AttributeName = attributeName;766767            return this;768        }769770        public IFluentOrderExpression Ascending()771        {772            _order.OrderType = OrderType.Ascending;773774            return this;760            _condition.Values.Add(value);761762            return this;763        }764765        public IFluentConditionExpression Value(params object[] value)766        {767            _condition.Values.AddRange(value);768769            return this;770        }771772        internal ConditionExpression GetCondition ()773        {774            return _condition;  775        }776777        public IFluentOrderExpression Descending()778        {779            _order.OrderType = OrderType.Descending;780781            return this;782        }783784        internal OrderExpression GetOrder()785        {786            return _order;787        }788    }789790    public interface IFluentPagingInfo791    {792        /**793         * <summary>794         * Set the page number to retrieve. Is set to 1 by default.795         * </summary>796         * <param name="number">Number of the page, starts at 1.</param>797         */798        IFluentPagingInfo PageNumber(int number);799800        /**801         * <summary>802         * Set the paging cookie for retrieving records from pages after the first.803         * </summary>804         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>805         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>806         */807        IFluentPagingInfo PagingCookie(string pagingCookie);808809        /**810         * <summary>811         * Set the size of each page.812         * </summary>813         * <param name="number">Number of records to return per page.</param>814         */815        IFluentPagingInfo PageSize(int number);816817        /**818         * <summary>819         * Specifies whether the total record count of your query results should be retrieved.820         * </summary>821         * <param name="returnTotal">True for returning total record count, false otherwise.</param>822         */823        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);824    }776    }777778    public interface IFluentOrderExpression779    {780        /**781         * <summary>782         * Set the attribute name to order by.783         * </summary>784         * <param name="attributeName">Attribute logical name</param>785         */786        IFluentOrderExpression By(string attributeName);787788        /**789         * <summary>790         * Sets the sort order to be ascending.791         * </summary>792         */793        IFluentOrderExpression Ascending();794795        /**796         * <summary>797         * Sets the sort order to be descending.798         * </summary>799         */800        IFluentOrderExpression Descending();801    }802803    public class FluentOrderExpression : IFluentOrderExpression804    {805        private OrderExpression _order;806807        public FluentOrderExpression ()808        {809            _order = new OrderExpression();810        }811812        public IFluentOrderExpression By(string attributeName)813        {814            _order.AttributeName = attributeName;815816            return this;817        }818819        public IFluentOrderExpression Ascending()820        {821            _order.OrderType = OrderType.Ascending;822823            return this;824        }  825826    public class FluentPagingInfo : IFluentPagingInfo827    {828        private PagingInfo _pagingInfo;826        public IFluentOrderExpression Descending()827        {828            _order.OrderType = OrderType.Descending;  829830        public FluentPagingInfo()831        {832            _pagingInfo = new PagingInfo833            {834                PageNumber = 1835            };830            return this;831        }832833        internal OrderExpression GetOrder()834        {835            return _order;  836        }837838        public IFluentPagingInfo PageNumber(int number)839        {840            _pagingInfo.PageNumber = number;841842            return this;843        }844845        public IFluentPagingInfo PageSize(int number)846        {847            _pagingInfo.Count = number;837    }838839    public interface IFluentPagingInfo840    {841        /**842         * <summary>843         * Set the page number to retrieve. Is set to 1 by default.844         * </summary>845         * <param name="number">Number of the page, starts at 1.</param>846         */847        IFluentPagingInfo PageNumber(int number);  848849            return this;850        }851852        public IFluentPagingInfo PagingCookie(string pagingCookie)853        {854            _pagingInfo.PagingCookie = pagingCookie;855856            return this;857        }858859        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)860        {861            _pagingInfo.ReturnTotalRecordCount = returnTotal;862863            return this;864        }849        /**850         * <summary>851         * Set the paging cookie for retrieving records from pages after the first.852         * </summary>853         * <remarks>Use retrieve all for automatic retrieval of all records using paging.</remarks>854         * <param name="pagingCookie">Paging cookie retrieved during last query response.</param>855         */856        IFluentPagingInfo PagingCookie(string pagingCookie);857858        /**859         * <summary>860         * Set the size of each page.861         * </summary>862         * <param name="number">Number of records to return per page.</param>863         */864        IFluentPagingInfo PageSize(int number);  865866        public PagingInfo GetPagingInfo()867        {868            return _pagingInfo;869        }870    }871}866        /**867         * <summary>868         * Specifies whether the total record count of your query results should be retrieved.869         * </summary>870         * <param name="returnTotal">True for returning total record count, false otherwise.</param>871         */872        IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true);873    }874875    public class FluentPagingInfo : IFluentPagingInfo876    {877        private PagingInfo _pagingInfo;878879        public FluentPagingInfo()880        {881            _pagingInfo = new PagingInfo882            {883                PageNumber = 1884            };885        }886887        public IFluentPagingInfo PageNumber(int number)888        {889            _pagingInfo.PageNumber = number;890891            return this;892        }893894        public IFluentPagingInfo PageSize(int number)895        {896            _pagingInfo.Count = number;897898            return this;899        }900901        public IFluentPagingInfo PagingCookie(string pagingCookie)902        {903            _pagingInfo.PagingCookie = pagingCookie;904905            return this;906        }907908        public IFluentPagingInfo ReturnTotalRecordCount(bool returnTotal = true)909        {910            _pagingInfo.ReturnTotalRecordCount = returnTotal;911912            return this;913        }914915        public PagingInfo GetPagingInfo()916        {917            return _pagingInfo;918        }919    }920} - +

Methods/Properties

diff --git a/reports/combined.js b/reports/combined.js index b3f9a07..3ff629c 100644 --- a/reports/combined.js +++ b/reports/combined.js @@ -325,13 +325,13 @@ var assemblies = [ { "name": "Xrm.Oss.FluentQuery", "classes": [ - { "name": "Xrm.Oss.FluentQuery.FluentConditionExpression", "reportPath": "Xrm.Oss.FluentQuery_FluentConditionExpression.htm", "coveredLines": 33, "uncoveredLines": 0, "coverableLines": 33, "totalLines": 871, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, - { "name": "Xrm.Oss.FluentQuery.FluentFilterExpression", "reportPath": "Xrm.Oss.FluentQuery_FluentFilterExpression.htm", "coveredLines": 26, "uncoveredLines": 0, "coverableLines": 26, "totalLines": 871, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, - { "name": "Xrm.Oss.FluentQuery.FluentLinkEntity", "reportPath": "Xrm.Oss.FluentQuery_FluentLinkEntity.htm", "coveredLines": 53, "uncoveredLines": 0, "coverableLines": 53, "totalLines": 871, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, - { "name": "Xrm.Oss.FluentQuery.FluentOrderExpression", "reportPath": "Xrm.Oss.FluentQuery_FluentOrderExpression.htm", "coveredLines": 19, "uncoveredLines": 0, "coverableLines": 19, "totalLines": 871, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, - { "name": "Xrm.Oss.FluentQuery.FluentPagingInfo", "reportPath": "Xrm.Oss.FluentQuery_FluentPagingInfo.htm", "coveredLines": 26, "uncoveredLines": 0, "coverableLines": 26, "totalLines": 871, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, - { "name": "Xrm.Oss.FluentQuery.FluentQuery`1", "reportPath": "Xrm.Oss.FluentQuery_FluentQuery_1.htm", "coveredLines": 85, "uncoveredLines": 0, "coverableLines": 85, "totalLines": 871, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 1, "totalBranches": 2, "lineCoverageHistory": [], "branchCoverageHistory": [] }, - { "name": "Xrm.Oss.FluentQuery.IOrganizationServiceFluentQuery", "reportPath": "Xrm.Oss.FluentQuery_IOrganizationServiceFluentQuery.htm", "coveredLines": 9, "uncoveredLines": 0, "coverableLines": 9, "totalLines": 871, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, + { "name": "Xrm.Oss.FluentQuery.FluentConditionExpression", "reportPath": "Xrm.Oss.FluentQuery_FluentConditionExpression.htm", "coveredLines": 33, "uncoveredLines": 0, "coverableLines": 33, "totalLines": 920, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, + { "name": "Xrm.Oss.FluentQuery.FluentFilterExpression", "reportPath": "Xrm.Oss.FluentQuery_FluentFilterExpression.htm", "coveredLines": 26, "uncoveredLines": 0, "coverableLines": 26, "totalLines": 920, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, + { "name": "Xrm.Oss.FluentQuery.FluentLinkEntity", "reportPath": "Xrm.Oss.FluentQuery_FluentLinkEntity.htm", "coveredLines": 53, "uncoveredLines": 0, "coverableLines": 53, "totalLines": 920, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, + { "name": "Xrm.Oss.FluentQuery.FluentOrderExpression", "reportPath": "Xrm.Oss.FluentQuery_FluentOrderExpression.htm", "coveredLines": 19, "uncoveredLines": 0, "coverableLines": 19, "totalLines": 920, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, + { "name": "Xrm.Oss.FluentQuery.FluentPagingInfo", "reportPath": "Xrm.Oss.FluentQuery_FluentPagingInfo.htm", "coveredLines": 26, "uncoveredLines": 0, "coverableLines": 26, "totalLines": 920, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, + { "name": "Xrm.Oss.FluentQuery.FluentQuery`1", "reportPath": "Xrm.Oss.FluentQuery_FluentQuery_1.htm", "coveredLines": 100, "uncoveredLines": 0, "coverableLines": 100, "totalLines": 920, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 1, "totalBranches": 2, "lineCoverageHistory": [], "branchCoverageHistory": [] }, + { "name": "Xrm.Oss.FluentQuery.IOrganizationServiceFluentQuery", "reportPath": "Xrm.Oss.FluentQuery_IOrganizationServiceFluentQuery.htm", "coveredLines": 9, "uncoveredLines": 0, "coverableLines": 9, "totalLines": 920, "coverageType": "LineCoverage", "methodCoverage": "-", "coveredBranches": 0, "totalBranches": 0, "lineCoverageHistory": [], "branchCoverageHistory": [] }, ]}, ]; diff --git a/reports/index.htm b/reports/index.htm index d803cf8..4c1b6e4 100644 --- a/reports/index.htm +++ b/reports/index.htm @@ -14,15 +14,15 @@

Summary

-Generated on:02.05.2018 - 00:24:40 +Generated on:02.05.2018 - 22:15:31 Parser:OpenCoverParser Assemblies:1 Classes:7 Files:1 -Covered lines:251 +Covered lines:266 Uncovered lines:0 -Coverable lines:251 -Total lines:871 +Coverable lines:266 +Total lines:920 Line coverage:100% Branch coverage:50% @@ -46,16 +46,16 @@

Coverage

NameCoveredUncoveredCoverableTotalLine coverageBranch coverage -Xrm.Oss.FluentQuery25102516097100%
 
50%
  
-Xrm.Oss.FluentQuery.FluentConditionExpression33033871100%
 
 
-Xrm.Oss.FluentQuery.FluentFilterExpression26026871100%
 
 
-Xrm.Oss.FluentQuery.FluentLinkEntity53053871100%
 
 
-Xrm.Oss.FluentQuery.FluentOrderExpression19019871100%
 
 
-Xrm.Oss.FluentQuery.FluentPagingInfo26026871100%
 
 
-Xrm.Oss.FluentQuery.FluentQuery`185085871100%
 
50%
  
-Xrm.Oss.FluentQuery.IOrganizationServiceFluentQuery909871100%
 
 
+Xrm.Oss.FluentQuery26602666440100%
 
50%
  
+Xrm.Oss.FluentQuery.FluentConditionExpression33033920100%
 
 
+Xrm.Oss.FluentQuery.FluentFilterExpression26026920100%
 
 
+Xrm.Oss.FluentQuery.FluentLinkEntity53053920100%
 
 
+Xrm.Oss.FluentQuery.FluentOrderExpression19019920100%
 
 
+Xrm.Oss.FluentQuery.FluentPagingInfo26026920100%
 
 
+Xrm.Oss.FluentQuery.FluentQuery`11000100920100%
 
50%
  
+Xrm.Oss.FluentQuery.IOrganizationServiceFluentQuery909920100%
 
 
-
+ \ No newline at end of file diff --git a/src/lib/Xrm.Oss.FluentQuery/FluentQuery.cs b/src/lib/Xrm.Oss.FluentQuery/FluentQuery.cs index 09116fd..71aa185 100644 --- a/src/lib/Xrm.Oss.FluentQuery/FluentQuery.cs +++ b/src/lib/Xrm.Oss.FluentQuery/FluentQuery.cs @@ -82,6 +82,13 @@ public interface IFluentQuery where T : Entity */ IFluentQuery IncludeColumns(params string[] columns); + /** + * + * Adds all columns to the query. This is disadvised, specify the columns you need if possible. + * + */ + IFluentQuery IncludeAllColumns(); + /** * * Returns the Query Expression that represents the current fluent query. @@ -129,6 +136,22 @@ public interface IFluentQuery where T : Entity */ IFluentQuery Where(Action definition); + /** + * + * Adds another condition to the top level filter expression. + * + * The condition expression to add. + */ + void AddCondition(Action definition); + + /** + * + * Adds a child filter to your top level filter. + * + * Action for setting the filter properties. Use a lambda for readability. + */ + void AddFilter(Action definition); + /** * * Adds an order expression to your query. @@ -201,11 +224,19 @@ public FluentQuery(string entityName, IOrganizationService service) public IFluentQuery IncludeColumns(params string[] columns) { + _query.ColumnSet.AllColumns = false; _query.ColumnSet.AddColumns(columns); return this; } + public IFluentQuery IncludeAllColumns() + { + _query.ColumnSet.AllColumns = true; + + return this; + } + public IFluentQuerySetting With { get @@ -296,6 +327,24 @@ public IFluentQuery Where(Action definition) return this; } + public void AddCondition(Action definition) + { + var condition = new FluentConditionExpression(); + + definition(condition); + + _query.Criteria.AddCondition(condition.GetCondition()); + } + + public void AddFilter(Action definition) + { + var filter = new FluentFilterExpression(); + + definition(filter); + + _query.Criteria.AddFilter(filter.GetFilter()); + } + public IFluentQuery Order(Action definition) { var order = new FluentOrderExpression(); diff --git a/src/test/Xrm.Oss.FluentQuery.Tests/FluentQueryTests.cs b/src/test/Xrm.Oss.FluentQuery.Tests/FluentQueryTests.cs index 1528979..46086ca 100644 --- a/src/test/Xrm.Oss.FluentQuery.Tests/FluentQueryTests.cs +++ b/src/test/Xrm.Oss.FluentQuery.Tests/FluentQueryTests.cs @@ -93,6 +93,39 @@ public void It_Should_Execute_Simple_Query() Assert.That(record.GetAttributeValue("address1_line1"), Is.EqualTo(testAddress)); } + [Test] + public void It_Should_Add_All_Columns() + { + var context = new XrmFakedContext(); + + var testName = "Adventure Works"; + var testAddress = "Somewhere over the rainbow"; + + var account = new Entity + { + Id = Guid.NewGuid(), + LogicalName = "account", + Attributes = + { + { "name", testName }, + { "address1_line1", testAddress } + } + }; + context.Initialize(new[] { account }); + + var service = context.GetFakedOrganizationService(); + + var records = service.Query("account") + .IncludeAllColumns() + .Retrieve(); + + Assert.That(records.Count, Is.EqualTo(1)); + + var record = records.Single(); + Assert.That(record.GetAttributeValue("name"), Is.EqualTo(testName)); + Assert.That(record.GetAttributeValue("address1_line1"), Is.EqualTo(testAddress)); + } + [Test] public void It_Should_Retrieve_All() { @@ -290,5 +323,96 @@ public void It_Should_Properly_Execute_Query() Assert.That(result[0].Id, Is.EqualTo(account.Id)); Assert.That(result[0].GetAttributeValue("name"), Is.EqualTo("Adventure Works")); } + + [Test] + public void It_Should_Add_Condition_Post_Creation() + { + var context = new XrmFakedContext(); + var service = context.GetFakedOrganizationService(); + + var query = service.Query("account"); + + query.AddCondition(c => c + .Named("emailaddress1") + .Is(ConditionOperator.NotNull) + ); + + var expression = query.Expression; + + Assert.That(expression.Criteria.Conditions[0].AttributeName, Is.EqualTo("emailaddress1")); + Assert.That(expression.Criteria.Conditions[0].Operator, Is.EqualTo(ConditionOperator.NotNull)); + } + + [Test] + public void It_Should_Add_Filter_Post_Creation() + { + var context = new XrmFakedContext(); + var service = context.GetFakedOrganizationService(); + + var query = service.Query("account") + .Where(e => e + .Attribute(a => a + .Of("contact") + .Named("name") + .Is(ConditionOperator.Equal) + .Value("Test") + ) + .With.Operator(LogicalOperator.And) + ); + + query.AddFilter(f => f + .Attribute(a => a + .Named("emailaddress1") + .Is(ConditionOperator.NotNull) + ) + ); + + var expression = query.Expression; + + Assert.That(expression.Criteria.FilterOperator, Is.EqualTo(LogicalOperator.And)); + Assert.That(expression.Criteria.Conditions[0].EntityName, Is.EqualTo("contact")); + Assert.That(expression.Criteria.Conditions[0].AttributeName, Is.EqualTo("name")); + Assert.That(expression.Criteria.Conditions[0].Operator, Is.EqualTo(ConditionOperator.Equal)); + Assert.That(expression.Criteria.Conditions[0].Values, Is.EqualTo(new[] { "Test" })); + + Assert.That(expression.Criteria.Filters[0].Conditions[0].AttributeName, Is.EqualTo("emailaddress1")); + Assert.That(expression.Criteria.Filters[0].Conditions[0].Operator, Is.EqualTo(ConditionOperator.NotNull)); + } + + [Test] + public void It_Should_Add_Top_Level_Filter_Post_Creation() + { + var context = new XrmFakedContext(); + var service = context.GetFakedOrganizationService(); + + var query = service.Query("account") + .Where(e => e + .Attribute(a => a + .Of("contact") + .Named("name") + .Is(ConditionOperator.Equal) + .Value("Test") + ) + .With.Operator(LogicalOperator.And) + ); + + query.AddFilter(f => f + .Attribute(a => a + .Named("emailaddress1") + .Is(ConditionOperator.NotNull) + ) + ); + + var expression = query.Expression; + + Assert.That(expression.Criteria.FilterOperator, Is.EqualTo(LogicalOperator.And)); + Assert.That(expression.Criteria.Conditions[0].EntityName, Is.EqualTo("contact")); + Assert.That(expression.Criteria.Conditions[0].AttributeName, Is.EqualTo("name")); + Assert.That(expression.Criteria.Conditions[0].Operator, Is.EqualTo(ConditionOperator.Equal)); + Assert.That(expression.Criteria.Conditions[0].Values, Is.EqualTo(new[] { "Test" })); + + Assert.That(expression.Criteria.Filters[0].Conditions[0].AttributeName, Is.EqualTo("emailaddress1")); + Assert.That(expression.Criteria.Filters[0].Conditions[0].Operator, Is.EqualTo(ConditionOperator.NotNull)); + } } }