PascalEugster
08/18/2023, 12:59 PMAnders Bjerner
08/18/2023, 1:03 PMPascalEugster
08/18/2023, 1:05 PMAnders Bjerner
08/18/2023, 1:15 PMPascalEugster
08/18/2023, 1:18 PMAnders Bjerner
08/18/2023, 1:20 PMISearchResult
would be more performant than using the content cache and IPublishedContent
.Anders Bjerner
08/18/2023, 1:21 PMAnders Bjerner
08/18/2023, 1:26 PMIRelationsService
to fetch relations. But this also hits the database, and might be a bit expensive. Possibly you can query the underlying database on your own with a more optimized query.PascalEugster
08/18/2023, 1:34 PMAnders Bjerner
08/18/2023, 1:44 PMsql
SELECT [ChildId], COUNT(*) AS [Count]
FROM [umbracoRelation]
WHERE [relType] = 4
GROUP BY [ChildId]
ORDER BY [Count] DESC;
IRelationService
and the underlying database table use numeric IDs, so you can grab the ChildId
and look up the pages in the content cache.
You can use Umbraco to access the database through IScopeProvider
, use it to create a new scope, and then IIRC that scope instance has a database property, which again has a Fetch
method. From memory, this would look something like:
csharp
using IScope scope = _scopeProvider.CreateScope();
var rows = scope.Database.Fetch<YourCustomDto>(yourCustomSql);
Anders Bjerner
08/18/2023, 1:45 PMPascalEugster
08/18/2023, 1:46 PMPascalEugster
08/18/2023, 1:46 PMAnders Bjerner
08/18/2023, 1:48 PMGetAllRelations
method will look for those rather than the page IDs.PascalEugster
08/18/2023, 1:49 PMAnders Bjerner
08/18/2023, 1:50 PMGetByChildId
method, which you may use, but then you have to call this for each page in allDossiers
, and then group and sort them by their count afterwards.Anders Bjerner
08/18/2023, 1:54 PMsql
SELECT [ChildId], COUNT(*) AS [Count]
FROM [umbracoRelation]
WHERE [relType] = 4 AND [ChildId] IN (1138, 1158, 1256)
GROUP BY [ChildId]
ORDER BY [Count] DESC;
PascalEugster
08/18/2023, 1:55 PMPascalEugster
08/18/2023, 1:57 PMAnders Bjerner
08/18/2023, 1:59 PMcsharp
public class RelationDto {
public int ChildId { get; set; }
public int Count{ get; set; }
}
Anders Bjerner
08/18/2023, 2:06 PMcsharp
@using Umbraco.Cms.Infrastructure.Scoping
@using Newtonsoft.Json.Linq
@inherits UmbracoViewPage
@inject IScopeProvider ScopeProvider
@functions {
public class RelationDto {
public int ChildId { get; set; }
public int Count { get; set; }
}
}
@{
string sql = "SELECT [ChildId], COUNT(*) AS [Count] FROM [umbracoRelation] WHERE [relType] = 4 AND [ChildId] IN (1138, 1158, 1256) GROUP BY [ChildId] ORDER BY [Count] DESC;";
using IScope scope = ScopeProvider.CreateScope();
List<RelationDto> rows = scope.Database.Fetch<RelationDto>(sql);
<pre>@JToken.FromObject(rows)</pre>
}
PascalEugster
08/18/2023, 2:18 PMPascalEugster
08/18/2023, 2:18 PMPascalEugster
08/18/2023, 2:18 PMAnders Bjerner
08/18/2023, 2:20 PMAnders Bjerner
08/18/2023, 2:20 PMsql
SELECT [ChildId], COUNT(*) AS [Count] FROM [umbracoRelation] WHERE [relType] = 4 AND [ParentId] IN (1104,1105,1106,1107) GROUP BY [ChildId] ORDER BY [Count] DESC;
PascalEugster
08/18/2023, 2:24 PMAnders Bjerner
08/18/2023, 2:28 PM4
is media relations, whereas 5
is document/content relations. Al least in my case. I just saw that I got results back, and though it was for content 😮
So might be good to either remove that part of the WHERE clause, or use IRelationService
to look up the relation type with the alias umbDocument
.PascalEugster
08/18/2023, 2:43 PMC#
public IEnumerable<Dossier> GetDossiersWithMostArticles()
{
var allDossiers = GetAllDossiers().ToList();
int[] dossierIds = allDossiers.Select(x => x.Id).ToArray();
string sql = $"SELECT [ChildId], COUNT(*) AS [Count] FROM [umbracoRelation] WHERE [ChildId] IN ({string.Join(",",dossierIds)}) GROUP BY [ChildId] ORDER BY [Count] DESC;";
using IScope scope = _scopeProvider.CreateScope();
List<RelationDto> rows = scope.Database.Fetch<RelationDto>(sql);
List<Dossier> sortedDossiers;
foreach (var row in rows)
{
if (_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext))
{
var content = umbracoContext.Content?.GetById(row.ChildId);
if(content is Dossier dossier)
{
yield return dossier;
}
}
}
}
PascalEugster
08/18/2023, 2:43 PMAnders Bjerner
08/18/2023, 2:44 PMAnders Bjerner
08/18/2023, 2:44 PMcsharp
public IEnumerable<Dossier> GetDossiersWithMostArticles()
{
var allDossiers = GetAllDossiers().ToList();
int[] dossierIds = allDossiers.Select(x => x.Id).ToArray();
string sql = $"SELECT [ChildId], COUNT(*) AS [Count] FROM [umbracoRelation] WHERE [ChildId] IN ({string.Join(",",dossierIds)}) GROUP BY [ChildId] ORDER BY [Count] DESC;";
using IScope scope = _scopeProvider.CreateScope();
List<RelationDto> rows = scope.Database.Fetch<RelationDto>(sql);
List<Dossier> sortedDossiers;
foreach (var row in rows)
{
if (_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext))
{
var content = umbracoContext.Content?.GetById(row.ChildId);
if(content is Dossier dossier)
{
yield return dossier;
}
}
}
}
Anders Bjerner
08/18/2023, 2:48 PM.ToList()
and .ToArray()
calls are redundant, as you can pass IEnumerable<id>
on to the string.Join()
method.
- sortedDossiers
variable doesn't appear to be usedAnders Bjerner
08/18/2023, 2:57 PMcsharp
public IEnumerable<Dossier> GetDossiersWithMostArticles() {
// Try to get a reference to the current Umbraco context
if (!_umbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext? umbracoContext)) return Enumerable.Empty<Dossier>();
// According to code analysis, the "Content" property may be null, so we'd better add a null check
if (umbracoContext.Content is null) return Enumerable.Empty<Dossier>();
// Get the IDs for the dossiers
IEnumerable<int> dossierIds = GetAllDossiers().Select(x => x.Id);
// TODO: Somehow add check for whether "dossierIds" is empty as the SQL query otherwise will fail
// Declare the SQL for the call to the database
string sql = $"SELECT [ChildId], COUNT(*) AS [Count] FROM [umbracoRelation] WHERE [ChildId] IN ({string.Join(",", dossierIds)}) GROUP BY [ChildId] ORDER BY [Count] DESC;";
// Create a new scope
using IScope scope = _scopeProvider.CreateScope();
// Make the call to the database
return scope.Database
.Fetch<RelationDto>(sql)
.Select(x => umbracoContext.Content!.GetById(x.ChildId))
.OfType<Dossier>();
}
PascalEugster
08/21/2023, 5:56 AM