@@ -1,263 +1,347 @@
// using System.Linq.Dynamic.Core;
// using System.Net ;
// using Volo.Abp.Auditing ;
// using Volo.Abp.Domain.Entities ;
// using Yi.Framework.SqlSugarCore.Abstractions ;
// using Yi.Framework.SqlSugarCore.Repositories ;
using System.Linq.Dynamic.Core ;
using System.Linq.Expressions ;
using System.Net ;
using Mapster ;
using SqlSugar ;
using Volo.Abp.Auditing ;
using Volo.Abp.Domain.Entities ;
using Volo.Abp.Domain.Repositories ;
using Yi.AuditLogging.SqlSugarCore.Entities ;
using Yi.Framework.SqlSugarCore.Repositories ;
// namespace Volo.Abp.AuditLogging.EntityFrameworkCore;
namespace Volo.Abp.AuditLogging.EntityFrameworkCore ;
// public class SqlSugarCoreAuditLogRepository : SqlSugarNoConstraints Repository< AuditLog,Guid>, IAuditLogRepository
// {
public class SqlSugarCoreAuditLogRepository : SqlSugarObject Repository< AuditLog, Guid > , IAuditLogRepository
{
public virtual async Task < List < AuditLog > > GetListAsync (
string sorting = null ,
int maxResultCount = 50 ,
int skipCount = 0 ,
DateTime ? startTime = null ,
DateTime ? endTime = null ,
string httpMethod = null ,
string url = null ,
Guid ? userId = null ,
string userName = null ,
string applicationName = null ,
string clientIpAddress = null ,
string correlationId = null ,
int? maxExecutionDuration = null ,
int? minExecutionDuration = null ,
bool? hasException = null ,
HttpStatusCode ? httpStatusCode = null ,
bool includeDetails = false ,
CancellationToken cancellationToken = default )
{
var query = await GetListQueryAsync (
startTime ,
endTime ,
httpMethod ,
url ,
userId ,
userName ,
applicationName ,
clientIpAddress ,
correlationId ,
maxExecutionDuration ,
minExecutionDuration ,
hasException ,
httpStatusCode ,
includeDetails
) ;
// public virtual async Task<List<AuditLog>> GetListAsync(
// string sorting = null,
// int maxResultCount = 50,
// int skipCount = 0,
// DateTime? startTime = null,
// DateTime? endTime = null,
// string httpMethod = null,
// string url = null,
// Guid? userId = null,
// string userName = null,
// string applicationName = null,
// string clientIpAddress = null,
// string correlationId = null,
// int? maxExecutionDuration = null,
// int? minExecutionDuration = null,
// bool? hasException = null,
// HttpStatusCode? httpStatusCode = null,
// bool includeDetails = false,
// CancellationToken cancellationToken = default)
// {
// var query = await GetListQueryAsync(
// startTime,
// endTime,
// httpMethod,
// url,
// userId,
// userName,
// applicationName,
// clientIpAddress,
// correlationId,
// maxExecutionDuration,
// minExecutionDuration,
// hasException,
// httpStatusCode,
// includeDetails
// );
var auditLogs = await query
. OrderBy ( sorting . IsNullOrWhiteSpace ( ) ? ( nameof ( AuditLog . ExecutionTime ) + " DESC" ) : sorting )
. ToPageListAsync ( skipCount , maxResultCount , cancellationToken ) ;
// var auditLogs = await query
// .OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(AuditLog.ExecutionTime) + " DESC") : sorting)
// .PageBy(skipCount, maxResultCount)
// .ToListAsync(GetCancellationToken(cancellationToken));
return auditLogs . Adapt < List < AuditLog > > ( ) ;
}
// return auditLogs;
// }
public virtual async Task < long > GetCountAsync (
DateTime ? startTime = null ,
DateTime ? endTime = null ,
string httpMethod = null ,
string url = null ,
Guid ? userId = null ,
string userName = null ,
string applicationName = null ,
string clientIpAddress = null ,
string correlationId = null ,
int? maxExecutionDuration = null ,
int? minExecutionDuration = null ,
bool? hasException = null ,
HttpStatusCode ? httpStatusCode = null ,
CancellationToken cancellationToken = default )
{
var query = await GetListQueryAsync (
startTime ,
endTime ,
httpMethod ,
url ,
userId ,
userName ,
applicationName ,
clientIpAddress ,
correlationId ,
maxExecutionDuration ,
minExecutionDuration ,
hasException ,
httpStatusCode
) ;
// public virtual async Task<long> GetCountAsync(
// DateTime? startTime = null,
// DateTime? endTime = null,
// string httpMethod = null,
// string url = null,
// Guid? userId = null,
// string userName = null,
// string applicationName = null,
// string clientIpAddress = null,
// string correlationId = null,
// int? maxExecutionDuration = null,
// int? minExecutionDuration = null,
// bool? hasException = null,
// HttpStatusCode? httpStatusCode = null,
// CancellationToken cancellationToken = default)
// {
// var query = await GetListQueryAsync(
// startTime,
// endTime,
// httpMethod,
// url,
// userId,
// userName,
// applicationName,
// clientIpAddress,
// correlationId,
// maxExecutionDuration,
// minExecutionDuration,
// hasException,
// httpStatusCode
// );
var totalCount = await query . CountAsync ( cancellationToken ) ;
// var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken)) ;
return totalCount ;
}
// return totalCount;
// }
protected virtual async Task < ISugarQueryable < AuditLogEntity > > GetListQueryAsync (
DateTime ? startTime = null ,
DateTime ? endTime = null ,
string httpMethod = null ,
string url = null ,
Guid ? userId = null ,
string userName = null ,
string applicationName = null ,
string clientIpAddress = null ,
string correlationId = null ,
int? maxExecutionDuration = null ,
int? minExecutionDuration = null ,
bool? hasException = null ,
HttpStatusCode ? httpStatusCode = null ,
bool includeDetails = false )
{
var nHttpStatusCode = ( int? ) httpStatusCode ;
return ( await GetDbContextAsync ( ) ) . Queryable < AuditLogEntity > ( )
. WhereIF ( startTime . HasValue , auditLog = > auditLog . ExecutionTime > = startTime )
. WhereIF ( endTime . HasValue , auditLog = > auditLog . ExecutionTime < = endTime )
. WhereIF ( hasException . HasValue & & hasException . Value , auditLog = > auditLog . Exceptions ! = null & & auditLog . Exceptions ! = "" )
. WhereIF ( hasException . HasValue & & ! hasException . Value , auditLog = > auditLog . Exceptions = = null | | auditLog . Exceptions = = "" )
. WhereIF ( httpMethod ! = null , auditLog = > auditLog . HttpMethod = = httpMethod )
. WhereIF ( url ! = null , auditLog = > auditLog . Url ! = null & & auditLog . Url . Contains ( url ) )
. WhereIF ( userId ! = null , auditLog = > auditLog . UserId = = userId )
. WhereIF ( userName ! = null , auditLog = > auditLog . UserName = = userName )
. WhereIF ( applicationName ! = null , auditLog = > auditLog . ApplicationName = = applicationName )
. WhereIF ( clientIpAddress ! = null , auditLog = > auditLog . ClientIpAddress ! = null & & auditLog . ClientIpAddress = = clientIpAddress )
. WhereIF ( correlationId ! = null , auditLog = > auditLog . CorrelationId = = correlationId )
. WhereIF ( httpStatusCode ! = null & & httpStatusCode > 0 , auditLog = > auditLog . HttpStatusCode = = nHttpStatusCode )
. WhereIF ( maxExecutionDuration ! = null & & maxExecutionDuration . Value > 0 , auditLog = > auditLog . ExecutionDuration < = maxExecutionDuration )
. WhereIF ( minExecutionDuration ! = null & & minExecutionDuration . Value > 0 , auditLog = > auditLog . ExecutionDuration > = minExecutionDuration ) ;
}
// protected virtual async Task<IQueryable<AuditLog>> GetListQuer yAsync(
// DateTime? startTime = null ,
// DateTime? endTime = null ,
// string httpMethod = null,
// string url = null,
// Guid? userId = null,
// string userName = null,
// string applicationName = null,
// string clientIpAddress = null,
// string correlationId = null,
// int? maxExecutionDuration = null,
// int? minExecutionDuration = null,
// bool? hasException = null,
// HttpStatusCode? httpStatusCode = null,
// bool includeDetails = false)
// {
// var nHttpStatusCode = (int?)httpStatusCode;
// return (await GetDbSetAsync()).AsNoTracking()
// .IncludeDetails(includeDetails)
// .WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime)
// .WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime)
// .WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "")
// .WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions == "")
// .WhereIf(httpMethod != null, auditLog => auditLog.HttpMethod == httpMethod)
// .WhereIf(url != null, auditLog => auditLog.Url != null && auditLog.Url.Contains(url))
// .WhereIf(userId != null, auditLog => auditLog.UserId == userId)
// .WhereIf(userName != null, auditLog => auditLog.UserName == userName)
// .WhereIf(applicationName != null, auditLog => auditLog.ApplicationName == applicationName)
// .WhereIf(clientIpAddress != null, auditLog => auditLog.ClientIpAddress != null && auditLog.ClientIpAddress == clientIpAddress)
// .WhereIf(correlationId != null, auditLog => auditLog.CorrelationId == correlationId)
// .WhereIf(httpStatusCode != null && httpStatusCode > 0, auditLog => auditLog.HttpStatusCode == nHttpStatusCode)
// .WhereIf(maxExecutionDuration != null && maxExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration <= maxExecutionDuration)
// .WhereIf(minExecutionDuration != null && minExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration >= minExecutionDuration);
// }
public virtual async Task< Dictionary < DateTime , double > > GetAverageExecutionDurationPerDa yAsync (
DateTime startDate ,
DateTime endDate ,
CancellationToken cancellationToken = default )
{
var result = await ( await GetDbContextAsync ( ) ) . Queryable < AuditLogEntity > ( )
. Where ( a = > a . ExecutionTime < endDate . AddDays ( 1 ) & & a . ExecutionTime > startDate )
. OrderBy ( t = > t . ExecutionTime )
. GroupBy ( t = > new { t . ExecutionTime . Date } )
. Select ( g = > new { Day = SqlFunc . AggregateMin ( g . ExecutionTime ) , avgExecutionTime = SqlFunc . AggregateAvg ( g . ExecutionDuration ) } )
. ToListAsync ( cancellationToken ) ;
// public virtual async Task<Dictionary<DateTime, double>> GetAverageExecutionDurationPerDayAsync(
// DateTime startDate,
// DateTime endDate,
// CancellationToken cancellationToken = default)
// {
// var result = await (await GetDbSetAsync()).AsNoTracking()
// .Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate)
// .OrderBy(t => t.ExecutionTime)
// .GroupBy(t => new { t.ExecutionTime.Date })
// .Select(g => new { Day = g.Min(t => t.ExecutionTime), avgExecutionTime = g.Average(t => t.ExecutionDuration) })
// .ToListAsync(GetCancellationToken(cancellationToken));
return result . ToDictionary ( element = > element . Day . ClearTime ( ) , element = > ( double ) element . avgExecutionTime ) ;
}
// return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime);
// }
public virtual async Task < EntityChange > GetEntityChange (
Guid entityChangeId ,
CancellationToken cancellationToken = default )
{
var entityChange = await ( await GetDbContextAsync ( ) ) . Queryable < EntityChange > ( )
. Where ( x = > x . Id = = entityChangeId )
. OrderBy ( x = > x . Id )
. FirstAsync ( cancellationToken ) ;
// [Obsolete("Use WithDetailsAsync method.")]
// public override IQueryable<AuditLog> WithDetails()
// {
// return GetQueryable().IncludeDetails();
// }
if ( entityChange = = null )
{
throw new EntityNotFoundException ( typeof ( EntityChange ) ) ;
}
// public override async Task<IQueryable<AuditLog>> WithDetailsAsync()
// {
// return (await GetQueryableAsync()).IncludeDetails();
// }
return entityChange ;
}
// public virtual async Task< EntityChange> GetEntityChange(
// Guid entityChangeId ,
// CancellationToken cancellationToken = default)
// {
// var entityChange = await (await GetDbContextAsync()).Set<EntityChange>()
// .AsNoTracking()
// .IncludeDetails()
// .Where(x => x.Id == entityChangeId)
// .OrderBy(x => x.Id)
// .FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
public virtual async Task< List < EntityChange> > GetEntityChangeListAsync (
string sorting = null ,
int maxResultCount = 50 ,
int skipCount = 0 ,
Guid ? auditLogId = null ,
DateTime ? startTime = null ,
DateTime ? endTime = null ,
EntityChangeType ? changeType = null ,
string entityId = null ,
string entityTypeFullName = null ,
bool includeDetails = false ,
CancellationToken cancellationToken = default )
{
var query = await GetEntityChangeListQueryAsync ( auditLogId , startTime , endTime , changeType , entityId , entityTypeFullName , includeDetails ) ;
// if (entityChange == null )
// {
// throw new EntityNotFoundException(typeof(EntityChange));
// }
return await query . OrderBy ( sorting . IsNullOrWhiteSpace ( ) ? ( nameof ( EntityChange . ChangeTime ) + " DESC" ) : sorting )
. ToPageListAsync ( skipCount , maxResultCount , cancellationToken ) ;
}
// return entityChange;
// }
public virtual async Task < long > GetEntityChangeCountAsync (
Guid ? auditLogId = null ,
DateTime ? startTime = null ,
DateTime ? endTime = null ,
EntityChangeType ? changeType = null ,
string entityId = null ,
string entityTypeFullName = null ,
CancellationToken cancellationToken = default )
{
var query = await GetEntityChangeListQueryAsync ( auditLogId , startTime , endTime , changeType , entityId , entityTypeFullName ) ;
// public virtual async Task<List<EntityChange>> GetEntityChangeListAsync(
// string sorting = null,
// int maxResultCount = 50,
// int skipCount = 0,
// Guid? auditLogId = null,
// DateTime? startTime = null,
// DateTime? endTime = null,
// EntityChangeType? changeType = null,
// string entityId = null,
// string entityTypeFullName = null,
// bool includeDetails = false,
// CancellationToken cancellationToken = default)
// {
// var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails);
var totalCount = await query . CountAsync ( cancellationToken ) ;
// return await query.OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(EntityChange.ChangeTime) + " DESC") : sorting)
// .PageBy(skipCount, maxResultCount)
// .ToListAsync(GetCancellationToken(cancellationToken));
// }
return totalCount ;
}
// public virtual async Task<long> GetEntityChangeCount Async(
// Guid? auditLogId = null ,
// DateTime? startTime = null,
// DateTime? endTime = null,
// EntityChangeType? changeType = null,
// string entityId = null,
// string entityTypeFullName = null,
// CancellationToken cancellationToken = default)
// {
// var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
public virtual async Task< EntityChangeWithUsername > GetEntityChangeWithUsername Async (
Guid entityChangeId ,
CancellationToken cancellationToken = default )
{
var auditLog = await ( await GetDbContextAsync ( ) ) . Queryable < AuditLogEntity > ( )
. Where ( x = > x . EntityChanges . Any ( y = > y . Id = = entityChangeId ) ) . FirstAsync ( cancellationToken ) ;
// var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken));
return new EntityChangeWithUsername ( )
{
EntityChange = auditLog . EntityChanges . First ( x = > x . Id = = entityChangeId ) ,
UserName = auditLog . UserName
} ;
}
// return totalCount;
// }
public virtual async Task < List < EntityChangeWithUsername > > GetEntityChangesWithUsernameAsync (
string entityId ,
string entityTypeFullName ,
CancellationToken cancellationToken = default )
{
var dbContext = await GetDbContextAsync ( ) ;
// public virtual async Task<EntityChangeWithUsername> GetEntityChangeWithUsernameAsync(
// Guid entityChangeId,
// CancellationToken cancellationToken = default )
// {
// var auditLog = await (await GetDbSetAsync()).AsNoTracking().IncludeDetails()
// .Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId)).FirstAsync(GetCancellationToken(cancellationToken));
var query = dbContext . Queryable < EntityChange > ( )
. Where ( x = > x . EntityId = = entityId & & x . EntityTypeFullName = = entityTypeFullName ) ;
return await query . LeftJoin < AuditLogEntity > ( ( change , audit ) = > change . AuditLogId = = audit . Id )
. Select ( ( change , audit ) = > new EntityChangeWithUsername { EntityChange = change , UserName = audit . UserName } , true )
. OrderByDescending ( x = > x . EntityChange . ChangeTime ) . ToListAsync ( cancellationToken ) ;
// return new EntityChangeWithUsername()
// {
// EntityChange = auditLog.EntityChanges.First(x => x.Id == entityChangeId),
// UserName = auditLog.UserName
// };
// }
}
// public virtual async Task<List<EntityChangeWithUsername>> GetEntityChangesWithUsername Async(
// string entityId ,
// string entityTypeFullName ,
// CancellationToken cancellationToken = default)
// {
// var dbContext = await GetDbContextAsync();
protected virtual async Task< ISugarQueryable < EntityChange > > GetEntityChangeListQuery Async (
Guid ? auditLogId = null ,
DateTime ? startTime = null ,
DateTime ? endTime = null ,
EntityChangeType ? changeType = null ,
string entityId = null ,
string entityTypeFullName = null ,
bool includeDetails = false )
{
return ( await GetDbContextAsync ( ) )
. Queryable < EntityChange > ( )
. WhereIF ( auditLogId . HasValue , e = > e . AuditLogId = = auditLogId )
. WhereIF ( startTime . HasValue , e = > e . ChangeTime > = startTime )
. WhereIF ( endTime . HasValue , e = > e . ChangeTime < = endTime )
. WhereIF ( changeType . HasValue , e = > e . ChangeType = = changeType )
. WhereIF ( ! string . IsNullOrWhiteSpace ( entityId ) , e = > e . EntityId = = entityId )
. WhereIF ( ! string . IsNullOrWhiteSpace ( entityTypeFullName ) , e = > e . EntityTypeFullName . Contains ( entityTypeFullName ) ) ;
}
// var query = dbContext.Set<EntityChange>( )
// .AsNoTracking()
// .IncludeDetails()
// .Where(x => x.EntityId == entityId && x.EntityTypeFullName == entityTypeFullName);
Task < List < AuditLog > > IAuditLogRepository . GetListAsync ( string sorting , int maxResultCount , int skipCount , DateTime ? startTime , DateTime ? endTime , string httpMethod , string url , Guid ? userId , string userName , string applicationName , string clientIpAddress , string correlationId , int? maxExecutionDuration , int? minExecutionDuration , bool? hasException , HttpStatusCode ? httpStatusCode , bool includeDetails , CancellationToken cancellationToken )
{
throw new NotImplementedException ( ) ;
}
// return await (from e in query
// join auditLog in dbContext.AuditLogs on e.AuditLogId equals auditLog.Id
// select new EntityChangeWithUsername { EntityChange = e, UserName = auditLog.UserName })
// .OrderByDescending(x => x.EntityChange.ChangeTime).ToListAsync(GetCancellationToken(cancellationToken));
// }
// protected virtual async Task<IQueryable<EntityChange>> GetEntityChangeListQueryAsync(
// Guid? auditLogId = null,
// DateTime? startTime = null,
// DateTime? endTime = null,
// EntityChangeType? changeType = null,
// string entityId = null,
// string entityTypeFullName = null,
// bool includeDetails = false)
// {
// return (await GetDbContextAsync())
// .Set<EntityChange>()
// .AsNoTracking( )
// .IncludeDetails(includeDetails)
// .WhereIf(auditLogId.HasValue, e => e.AuditLogId == auditLogId)
// .WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime)
// .WhereIf(endTime.HasValue, e => e.ChangeTime <= endTime)
// .WhereIf(changeType.HasValue, e => e.ChangeType == changeType )
// .WhereIf(!string.IsNullOrWhiteSpace(entityId), e => e.EntityId == entityId)
// .WhereIf(!string.IsNullOrWhiteSpace(entityTypeFullName), e => e.EntityTypeFullName.Contains(entityTypeFullName)) ;
// }
//}
public Task < AuditLog > GetAsync ( Expression < Func < AuditLog , bool > > predicate , bool includeDetails = true , CancellationToken cancellationToken = default )
{
throw new NotImplementedException ( ) ;
}
public Task DeleteAsync ( Expression < Func < AuditLog , bool > > predicate , bool autoSave = false , CancellationToken cancellationToken = default )
{
throw new NotImplementedException ( ) ;
}
public Task DeleteDirectAsync ( Expression < Func < AuditLog , bool > > predicate , CancellationToken cancellationToken = default )
{
throw new NotImplementedException ( ) ;
}
IQueryable < AuditLog > IReadOnlyRepository < AuditLog > . WithDetails ( )
{
throw new NotImplementedException ( ) ;
}
public IQueryable < AuditLog > WithDetails ( params Expression < Func < AuditLog , object > > [ ] propertySelectors )
{
throw new NotImplementedException ( ) ;
}
Task < IQueryable < AuditLog > > IReadOnlyRepository < AuditLog > . WithDetailsAsync ( )
{
throw new NotImplementedException ( ) ;
}
public Task < IQueryable < AuditLog > > WithDetailsAsync ( params Expression < Func < AuditLog , object > > [ ] propertySelectors )
{
throw new NotImplementedException ( ) ;
}
Task < IQueryable < AuditLog > > IReadOnlyRepository < AuditLog > . GetQueryableAsync ( )
{
throw new NotImplementedException ( ) ;
}
public Task < List < AuditLog > > GetListAsync ( Expression < Func < AuditLog , bool > > predicate , bool includeDetails = false , CancellationToken cancellationToken = default )
{
throw new NotImplementedException ( ) ;
}
public Task < AuditLog > InsertAsync ( AuditLog entity , bool autoSave = false , CancellationToken cancellationToken = default )
{
throw new NotImplementedException ( ) ;
}
public Task InsertManyAsync ( IEnumerable < AuditLog > entities , bool autoSave = false , CancellationToken cancellationToken = default )
{
throw new NotImplementedException ( ) ;
}
public Task < AuditLog > UpdateAsync ( AuditLog entity , bool autoSave = false , CancellationToken cancellationToken = default )
{
throw new NotImplementedException ( ) ;
}
public Task UpdateManyAsync ( IEnumerable < AuditLog > entities , bool autoSave = false , CancellationToken cancellationToken = default )
{
throw new NotImplementedException ( ) ;
}
public Task DeleteAsync ( AuditLog entity , bool autoSave = false , CancellationToken cancellationToken = default )
{
throw new NotImplementedException ( ) ;
}
public Task DeleteManyAsync ( IEnumerable < AuditLog > entities , bool autoSave = false , CancellationToken cancellationToken = default )
{
throw new NotImplementedException ( ) ;
}
Task < AuditLog > IReadOnlyBasicRepository < AuditLog , Guid > . GetAsync ( Guid id , bool includeDetails , CancellationToken cancellationToken )
{
throw new NotImplementedException ( ) ;
}
Task < AuditLog ? > IReadOnlyBasicRepository < AuditLog , Guid > . FindAsync ( Guid id , bool includeDetails , CancellationToken cancellationToken )
{
throw new NotImplementedException ( ) ;
}
Task < List < AuditLog > > IReadOnlyBasicRepository < AuditLog > . GetListAsync ( bool includeDetails , CancellationToken cancellationToken )
{
throw new NotImplementedException ( ) ;
}
Task < List < AuditLog > > IReadOnlyBasicRepository < AuditLog > . GetPagedListAsync ( int skipCount , int maxResultCount , string sorting , bool includeDetails , CancellationToken cancellationToken )
{
throw new NotImplementedException ( ) ;
}
}