Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/wiredviews/xperience-query-extensions
This package provides helpful extension methods for the various Kentico Xperience Document/Object query APIs.
https://github.com/wiredviews/xperience-query-extensions
cms dotnet kentico-xperience
Last synced: 3 months ago
JSON representation
This package provides helpful extension methods for the various Kentico Xperience Document/Object query APIs.
- Host: GitHub
- URL: https://github.com/wiredviews/xperience-query-extensions
- Owner: wiredviews
- License: mit
- Created: 2020-12-13T18:50:08.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2023-01-26T19:02:19.000Z (about 2 years ago)
- Last Synced: 2024-09-18T17:38:43.325Z (5 months ago)
- Topics: cms, dotnet, kentico-xperience
- Language: C#
- Homepage:
- Size: 124 KB
- Stars: 1
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Xperience Query Extensions
[![GitHub Actions CI: Build](https://github.com/wiredviews/xperience-query-extensions/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/wiredviews/xperience-query-extensions/actions/workflows/ci.yml)
[![Publish Packages to NuGet](https://github.com/wiredviews/xperience-query-extensions/actions/workflows/publish.yml/badge.svg?branch=main)](https://github.com/wiredviews/xperience-query-extensions/actions/workflows/publish.yml)
[![NuGet Package](https://img.shields.io/nuget/v/XperienceCommunity.QueryExtensions.svg)](https://www.nuget.org/packages/XperienceCommunity.QueryExtensions)
This package provides a set of extension methods for Kentico Xperience 13.0 `DocumentQuery`, `MultiDocumentQuery`, `ObjectQuery`, and `IPageRetriever` [data access APIs](https://docs.xperience.io/13api/content-management/pages).
## Dependencies
This package is compatible with ASP.NET Core 3.1 -> ASP.NET Core 5 applications or libraries integrated with Kentico Xperience 13.0.
## How to Use?
1. Install the NuGet package in your ASP.NET Core project (or class library)
```bash
dotnet add package XperienceCommunity.QueryExtensions
```1. Add the correct `using` to have the extensions appear in intellisense
`using XperienceCommunity.QueryExtensions.Documents;`
`using XperienceCommunity.QueryExtensions.Objects;`
`using XperienceCommunity.QueryExtensions.Collections;`
> The extension methods are all in explicit namespaces to prevent conflicts with extensions that Xperience might add in the future or extensions that the developer might have already created.
>
> If you are using C# 10, you can apply these globally with [C# 10 implicit usings](https://docs.microsoft.com/en-us/dotnet/core/project-sdk/overview#implicit-using-directives)## Extension Methods
### DocumentQuery
#### Prerequisites
```csharp
using XperienceCommunity.QueryExtensions.Documents;
```#### Examples
> These work for both `DocumentQuery` and `MultiDocumentQuery`
```csharp
public void QueryDocument(Guid nodeGuid)
{
var query = DocumentHelper.GetDocuments()
.WhereNodeGUIDEquals(nodeGuid);
}
``````csharp
public void QueryDocument(int nodeID)
{
var query = DocumentHelper.GetDocuments()
.WhereNodeIDEquals(nodeID);
}
``````csharp
public void QueryDocument(int documentID)
{
var query = DocumentHelper.GetDocuments()
.WhereDocumentIDEquals(documentID);
}
``````csharp
var query = DocumentHelper.GetDocuments()
.OrderByNodeOrder();
``````csharp
var query = DocumentHelper.GetDocuments()
.Tap(q =>
{
// access the query 'q'
});
``````csharp
bool condition = ...var query = DocumentHelper.GetDocuments()
.If(condition, q =>
{
// when condition is true
});
``````csharp
bool condition = ...var query = DocumentHelper.GetDocuments()
.If(condition,
q =>
{
// when condition is true
},
q =>
{
// when condition is false
});
``````csharp
var query = DocumentHelper.GetDocuments()
.OrderByDescending(nameof(TreeNode.NodeID))
.TopN(1)
.DebugQuery();/*
--- BEGIN [path\to\your\app\Program.cs] QUERY ---DECLARE @DocumentCulture nvarchar(max) = N'en-US';
SELECT TOP 1 *
FROM View_CMS_Tree_Joined AS V WITH (NOLOCK, NOEXPAND) LEFT OUTER JOIN COM_SKU AS S WITH (NOLOCK) ON [V].[NodeSKUID] = [S].[SKUID]
WHERE [DocumentCulture] = @DocumentCulture
ORDER BY NodeID DESC--- END [path\to\your\app\Program.cs] QUERY ---
*/
``````csharp
var query = DocumentHelper.GetDocuments()
.OrderByDescending(nameof(TreeNode.NodeID))
.TopN(1)
.DebugQuery("Newest Document");/*
--- BEGIN [Newest Document] QUERY ---DECLARE @DocumentCulture nvarchar(max) = N'en-US';
SELECT TOP 1 *
FROM View_CMS_Tree_Joined AS V WITH (NOLOCK, NOEXPAND) LEFT OUTER JOIN COM_SKU AS S WITH (NOLOCK) ON [V].[NodeSKUID] = [S].[SKUID]
WHERE [DocumentCulture] = @DocumentCulture
ORDER BY NodeID DESC--- END [Newest Document] QUERY ---
*/
``````csharp
var query = DocumentHelper.GetDocuments()
.OrderByDescending(nameof(TreeNode.NodeID))
.TopN(1)
.TapQueryText(fullQueryText =>
{
Debug.WriteLine(fullQueryText);
})
.WhereEquals(...)
``````csharp
public void QueryDatabase(ILogger logger)
{
var query = DocumentHelper.GetDocuments()
.OrderByDescending(nameof(TreeNode.NodeID))
.TopN(1)
.LogQuery(logger, "Logged Query");
}
``````csharp
var query = DocumentHelper.GetDocuments()
.Where(w => w.WhereInPath("path1", "path2"));
```### ObjectQuery
#### Prerequisites
```csharp
using XperienceCommunity.QueryExtensions.Objects;
```#### Examples
```csharp
return UserInfo.Provider.Get()
.Tap(q =>
{
// access the query
});
``````csharp
bool condition = ...var query = UserInfo.Provider.Get()
.If(condition, q =>
{
// when condition is true
});
``````csharp
bool condition = ...var query = UserInfo.Provider.Get()
.If(condition,
q =>
{
// when condition is true
},
q =>
{
// when condition is false
});
``````csharp
var query = UserInfo.Provider.Get()
.OrderByDescending(nameof(UserInfo.UserLastModified))
.TopN(1)
.DebugQuery();/*
--- BEGIN [path\to\your\app\Program.cs] QUERY ---SELECT TOP 1 *
FROM CMS_User
ORDER BY UserLastModified DESC--- END [path\to\your\app\Program.cs] QUERY ---
*/
``````csharp
var query = UserInfo.Provider.Get()
.OrderByDescending(nameof(UserInfo.UserLastModified))
.TopN(1)
.DebugQuery("User");/*
--- QUERY [User] START ---SELECT TOP 1 *
FROM CMS_User
ORDER BY UserLastModified DESC--- QUERY [User] END ---
*/
``````csharp
public void QueryDatabase(ILogger logger)
{
var query = UserInfo.Provider.Get()
.OrderByDescending(nameof(UserInfo.UserLastModified))
.TopN(1)
.LogQuery(logger, "Logged User Query");
}
``````csharp
var query = UserInfo.Provider.Get()
.TapQueryText(text =>
{
// do something with the query text
});
``````csharp
var query = UserInfo.Provider.Get()
.Source(s => s.InnerJoin(
"UserID",
"UserSettingUserID",
"MY_ALIAS",
additionalCondition: new WhereCondition("MY_ALIAS.UserWaitingForApproval", QueryOperator.Equals, true),
hints: new[] { SqlHints.NOLOCK }))
.TopN(1)
.DebugQuery("User");/*
--- QUERY [User] START ---SELECT TOP 1 *
FROM CMS_User
INNER JOIN CMS_UserSetting AS MY_ALIAS WITH (NOLOCK) ON UserID = MY_ALIAS.UserSettingUserID AND MY_ALIAS.UserWaitingForApproval = 1
ORDER BY UserLastModified DESC--- QUERY [User] END ---
*/
``````csharp
// ExecuteAsync returns a populated dataset with all the columns returned by the query.
// When there are no results, dataset.Tables[0] will still be populated with an empty DataTable.var dataset = await UserInfo.Provider.Get()
.Source(source => source
.InnerJoin(
"UserID",
"UserSettingUserID",
"MY_ALIAS")
.InnerJoin(
"CustomerUserID",
"UserID",
"C",
)
)
.Columns("UserID", "UserSettingID", "CustomerID")
.ExecuteAsync();
foreach (var row in dataset.Tables[0].Rows)
{
Console.WriteLine($"User: {row["UserID"]}, User Setting: {row["UserSettingID"]}, Customer: {row["CustomerID"]}");
}
```### Collections
#### Requirements
```csharp
using XperienceCommunity.QueryExtensions.Collections;
```#### Examples
```csharp
TreeNode? page = await retriever
.RetrieveAsync(q => q.TopN(1), cancellationToken: token)
.FirstOrDefaultAsync();
``````csharp
IList pages = await retriever
.RetrieveAsync(cancellationToken: token)
.ToListAsync();
``````csharp
IList pages = await retriever
.RetrieveAsync(cancellationToken: token)
.ToArrayAsync();
```### PageRetriever
#### Requirements
```csharp
using Kentico.Content.Web.Mvc;
```#### Examples
```csharp
void GetPages(int pageIndex, int pageSize)
{
var result = await retriever.RetrievePagedAsync(
pageIndex,
pageSize,
q => q.OrderByNodeOrder(),
cancellationToken: token);int total = result.TotalRecords;
List pages = result.Items;// or
var (totalRecords, pages) = await retriever.RetrievePagedAsync(
pageIndex,
pageSize,
q => q.OrderByNodeOrder(),
cancellationToken: token);
}
```### XperienceCommunityConnectionHelper
#### Examples
```csharp
var dataSet = await XperienceCommunityConnectionHelper.ExecuteQueryAsync("CMS.User", "GetAllUsersCustom");
``````csharp
string queryText = @"
SELECT *
FROM CMS_User
WHERE UserID = @UserID
"var queryParams = new QueryDataParameters
{
{ "UserID", 3 }
};var dataSet = await XperienceCommunityConnectionHelper.ExecuteQueryAsync(queryText, queryParams, token: token);
```## References
### .NET
- [Nullable reference types (C# reference)](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/nullable-reference-types)
### Kentico Xperience
- [Kentico Xperience 13 Beta 3 - New Data Access APIs](https://dev.to/seangwright/kentico-xperience-13-beta-3-new-data-access-apis-1oha)
- [Pages API Examples](https://docs.xperience.io/13api/content-management/pages)
- [Retrieving pages in custom scenarios](https://docs.xperience.io/custom-development/working-with-pages-in-the-api#WorkingwithpagesintheAPI-Retrievingpagesincustomscenarios)
- [Improvements under the hood – Document and ObjectQuery enumeration without DataSets](https://devnet.kentico.com/articles/improvements-under-the-hood-document-and-objectquery-enumeration-without-datasets)