Skip to content

Commit

Permalink
Added functions for adding child filters and conditions post fluent q…
Browse files Browse the repository at this point in the history
…uery creation. Added NoLock explanation to ReadMe
  • Loading branch information
DigitalFlow committed May 2, 2018
1 parent 1cc7ccc commit e6b3c72
Show file tree
Hide file tree
Showing 14 changed files with 6,257 additions and 5,683 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,21 @@ 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.

This could look something like this (When not developing early bound, you can simply leave out the generic parameter):
```C#
var records = service.Query<Account>()
.IncludeColumns("name")
.IncludeColumns("name", "address1_line1")
.Where(e => e
.Attribute(a => a
.Named("name")
Expand All @@ -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
{
Expand Down
4 changes: 2 additions & 2 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ""
Expand Down
765 changes: 405 additions & 360 deletions coverage.xml

Large diffs are not rendered by default.

1,567 changes: 808 additions & 759 deletions reports/Xrm.Oss.FluentQuery_FluentConditionExpression.htm

Large diffs are not rendered by default.

1,557 changes: 803 additions & 754 deletions reports/Xrm.Oss.FluentQuery_FluentFilterExpression.htm

Large diffs are not rendered by default.

1,569 changes: 809 additions & 760 deletions reports/Xrm.Oss.FluentQuery_FluentLinkEntity.htm

Large diffs are not rendered by default.

1,561 changes: 805 additions & 756 deletions reports/Xrm.Oss.FluentQuery_FluentOrderExpression.htm

Large diffs are not rendered by default.

1,559 changes: 804 additions & 755 deletions reports/Xrm.Oss.FluentQuery_FluentPagingInfo.htm

Large diffs are not rendered by default.

1,583 changes: 819 additions & 764 deletions reports/Xrm.Oss.FluentQuery_FluentQuery_1.htm

Large diffs are not rendered by default.

1,551 changes: 800 additions & 751 deletions reports/Xrm.Oss.FluentQuery_IOrganizationServiceFluentQuery.htm

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions reports/combined.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 13 additions & 13 deletions reports/index.htm
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ <h1>Summary</h1>
<col />
</colgroup>
<tbody>
<tr><th>Generated on:</th><td>02.05.2018 - 00:24:40</td></tr>
<tr><th>Generated on:</th><td>02.05.2018 - 22:15:31</td></tr>
<tr><th>Parser:</th><td>OpenCoverParser</td></tr>
<tr><th>Assemblies:</th><td>1</td></tr>
<tr><th>Classes:</th><td>7</td></tr>
<tr><th>Files:</th><td>1</td></tr>
<tr><th>Covered lines:</th><td>251</td></tr>
<tr><th>Covered lines:</th><td>266</td></tr>
<tr><th>Uncovered lines:</th><td>0</td></tr>
<tr><th>Coverable lines:</th><td>251</td></tr>
<tr><th>Total lines:</th><td>871</td></tr>
<tr><th>Coverable lines:</th><td>266</td></tr>
<tr><th>Total lines:</th><td>920</td></tr>
<tr><th>Line coverage:</th><td>100%</td></tr>
<tr><th>Branch coverage:</th><td>50%</td></tr>
</tbody>
Expand All @@ -46,16 +46,16 @@ <h1>Coverage</h1>
</colgroup>
<thead><tr><th>Name</th><th class="right">Covered</th><th class="right">Uncovered</th><th class="right">Coverable</th><th class="right">Total</th><th class="center" colspan="2">Line coverage</th><th class="center" colspan="2">Branch coverage</th></tr></thead>
<tbody>
<tr><th>Xrm.Oss.FluentQuery</th><th class="right">251</th><th class="right">0</th><th class="right">251</th><th class="right">6097</th><th title="LineCoverage" class="right">100%</th><th><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></th><th class="right">50%</th><th><table class="coverage"><tr><td class="green covered50">&nbsp;</td><td class="red covered50">&nbsp;</td></tr></table></th></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentConditionExpression.htm">Xrm.Oss.FluentQuery.FluentConditionExpression</a></td><td class="right">33</td><td class="right">0</td><td class="right">33</td><td class="right">871</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentFilterExpression.htm">Xrm.Oss.FluentQuery.FluentFilterExpression</a></td><td class="right">26</td><td class="right">0</td><td class="right">26</td><td class="right">871</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentLinkEntity.htm">Xrm.Oss.FluentQuery.FluentLinkEntity</a></td><td class="right">53</td><td class="right">0</td><td class="right">53</td><td class="right">871</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentOrderExpression.htm">Xrm.Oss.FluentQuery.FluentOrderExpression</a></td><td class="right">19</td><td class="right">0</td><td class="right">19</td><td class="right">871</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentPagingInfo.htm">Xrm.Oss.FluentQuery.FluentPagingInfo</a></td><td class="right">26</td><td class="right">0</td><td class="right">26</td><td class="right">871</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentQuery_1.htm">Xrm.Oss.FluentQuery.FluentQuery`1</a></td><td class="right">85</td><td class="right">0</td><td class="right">85</td><td class="right">871</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right">50%</td><td><table class="coverage"><tr><td class="green covered50">&nbsp;</td><td class="red covered50">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_IOrganizationServiceFluentQuery.htm">Xrm.Oss.FluentQuery.IOrganizationServiceFluentQuery</a></td><td class="right">9</td><td class="right">0</td><td class="right">9</td><td class="right">871</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><th>Xrm.Oss.FluentQuery</th><th class="right">266</th><th class="right">0</th><th class="right">266</th><th class="right">6440</th><th title="LineCoverage" class="right">100%</th><th><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></th><th class="right">50%</th><th><table class="coverage"><tr><td class="green covered50">&nbsp;</td><td class="red covered50">&nbsp;</td></tr></table></th></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentConditionExpression.htm">Xrm.Oss.FluentQuery.FluentConditionExpression</a></td><td class="right">33</td><td class="right">0</td><td class="right">33</td><td class="right">920</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentFilterExpression.htm">Xrm.Oss.FluentQuery.FluentFilterExpression</a></td><td class="right">26</td><td class="right">0</td><td class="right">26</td><td class="right">920</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentLinkEntity.htm">Xrm.Oss.FluentQuery.FluentLinkEntity</a></td><td class="right">53</td><td class="right">0</td><td class="right">53</td><td class="right">920</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentOrderExpression.htm">Xrm.Oss.FluentQuery.FluentOrderExpression</a></td><td class="right">19</td><td class="right">0</td><td class="right">19</td><td class="right">920</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentPagingInfo.htm">Xrm.Oss.FluentQuery.FluentPagingInfo</a></td><td class="right">26</td><td class="right">0</td><td class="right">26</td><td class="right">920</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_FluentQuery_1.htm">Xrm.Oss.FluentQuery.FluentQuery`1</a></td><td class="right">100</td><td class="right">0</td><td class="right">100</td><td class="right">920</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right">50%</td><td><table class="coverage"><tr><td class="green covered50">&nbsp;</td><td class="red covered50">&nbsp;</td></tr></table></td></tr>
<tr><td><a href="Xrm.Oss.FluentQuery_IOrganizationServiceFluentQuery.htm">Xrm.Oss.FluentQuery.IOrganizationServiceFluentQuery</a></td><td class="right">9</td><td class="right">0</td><td class="right">9</td><td class="right">920</td><td title="LineCoverage" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td><td class="right"></td><td><table class="coverage"><tr><td class="gray covered100">&nbsp;</td></tr></table></td></tr>
</tbody>
</table>
<div class="footer">Generated by: ReportGenerator 3.1.2.0<br />02.05.2018 - 00:24:40<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div></div>
<div class="footer">Generated by: ReportGenerator 3.1.2.0<br />02.05.2018 - 22:15:31<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div></div>
<script type="text/javascript" src="combined.js"></script>
</body></html>
49 changes: 49 additions & 0 deletions src/lib/Xrm.Oss.FluentQuery/FluentQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ public interface IFluentQuery<T> where T : Entity
*/
IFluentQuery<T> IncludeColumns(params string[] columns);

/**
* <summary>
* Adds all columns to the query. This is disadvised, specify the columns you need if possible.
* </summary>
*/
IFluentQuery<T> IncludeAllColumns();

/**
* <summary>
* Returns the Query Expression that represents the current fluent query.
Expand Down Expand Up @@ -129,6 +136,22 @@ public interface IFluentQuery<T> where T : Entity
*/
IFluentQuery<T> Where(Action<IFluentFilterExpression> definition);

/**
* <summary>
* Adds another condition to the top level filter expression.
* </summary>
* <param name="definition">The condition expression to add.</param>
*/
void AddCondition(Action<IFluentConditionExpression> definition);

/**
* <summary>
* Adds a child filter to your top level filter.
* </summary>
* <param name="definition">Action for setting the filter properties. Use a lambda for readability.</param>
*/
void AddFilter(Action<IFluentFilterExpression> definition);

/**
* <summary>
* Adds an order expression to your query.
Expand Down Expand Up @@ -201,11 +224,19 @@ public FluentQuery(string entityName, IOrganizationService service)

public IFluentQuery<T> IncludeColumns(params string[] columns)
{
_query.ColumnSet.AllColumns = false;
_query.ColumnSet.AddColumns(columns);

return this;
}

public IFluentQuery<T> IncludeAllColumns()
{
_query.ColumnSet.AllColumns = true;

return this;
}

public IFluentQuerySetting<T> With
{
get
Expand Down Expand Up @@ -296,6 +327,24 @@ public IFluentQuery<T> Where(Action<IFluentFilterExpression> definition)
return this;
}

public void AddCondition(Action<IFluentConditionExpression> definition)
{
var condition = new FluentConditionExpression();

definition(condition);

_query.Criteria.AddCondition(condition.GetCondition());
}

public void AddFilter(Action<IFluentFilterExpression> definition)
{
var filter = new FluentFilterExpression();

definition(filter);

_query.Criteria.AddFilter(filter.GetFilter());
}

public IFluentQuery<T> Order(Action<IFluentOrderExpression> definition)
{
var order = new FluentOrderExpression();
Expand Down
Loading

0 comments on commit e6b3c72

Please sign in to comment.