/// <summary> /// Finds a collection of events with the given primary key value. /// </summary> /// <param name="id">Event ID (Primary Key).</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual async Task <IList <EventResult> > FindAllByIdAsync(int id, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); var list = new List <EventResult>(); var connection = Context.Database.Connection; try { await connection.OpenAsync(cancellationToken); using (var command = connection.CreateCommand()) { command.CommandText = "Logging.GetEventsById"; command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(DbParameters.Value("Id", id)); using (var reader = await command.ExecuteReaderAsync(cancellationToken)) { var mapper = new LoggingEventResultMapper(reader); while (reader.Read()) { list.Add(mapper.Translate()); } } } } finally { connection.Close(); } return(list); }
/// <summary> /// Finds a collection of events with the given values /// </summary> /// <param name="ownerId">Owner ID (Foreign Key)</param> /// <param name="categoryId">Category ID (Foreign Key)</param> /// <param name="projectId">Project ID (Foreign Key)</param> /// <param name="actionId">Action ID (Foreign Key)</param> /// <param name="pageId">Page ID (Foreign Key)</param> /// <param name="contactState">Contact state flag</param> /// <param name="dateFrom"></param> /// <param name="dateTo"></param> /// <param name="emails">A collection of contact emails.</param> /// <param name="clients">A collection of Client IDs.</param> /// <param name="pageIndex">The index of the page of results to return. Use 1 to indicate the first page.</param> /// <param name="pageSize">The size of the page of results to return. <paramref name="pageIndex" /> is non-zero-based.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual async Task <ListResult <EventResult> > FindAllAsync( int userId, int?categoryId, DateTime?dateFrom, DateTime?dateTo, ObjectType?objectType, int?objectId, int?contactId, ObjectState?contactState, int?projectId, string customUri, IEnumerable <string> emails, IEnumerable <string> clients, int pageIndex, int pageSize, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); var listBuilder = ImmutableArray.CreateBuilder <EventResult>(); var total = 0; var connection = Context.Database.Connection; try { await connection.OpenAsync(cancellationToken); // This solution has a considerable effect on performance avoiding EF Code First // object materialization. Log queries are performance critical. Do not be lazy :-) using (var command = connection.CreateCommand()) { command.CommandText = "Logging.GetEvents"; command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(DbParameters.Value("UserId", userId)); command.Parameters.Add(DbParameters.Value("CategoryId", categoryId)); command.Parameters.Add(DbParameters.Value("DateFrom", dateFrom)); command.Parameters.Add(DbParameters.Value("DateTo", dateTo)); command.Parameters.Add(DbParameters.Value("ObjectTypeId", objectType)); command.Parameters.Add(DbParameters.Value("ObjectId", objectId)); command.Parameters.Add(DbParameters.Value("ContactId", contactId)); command.Parameters.Add(DbParameters.Value("ContactStateId", contactState)); command.Parameters.Add(DbParameters.Value("ProjectId", projectId)); command.Parameters.Add(DbParameters.Value("CustomUri", customUri)); command.Parameters.Add(DbParameters.EmailList("Emails", emails)); command.Parameters.Add(DbParameters.ClientList("Clients", clients)); command.Parameters.Add(DbParameters.Value("PageIndex", pageIndex)); command.Parameters.Add(DbParameters.Value("PageSize", pageSize)); command.Parameters.Add(DbParameters.Value("TotalItemCount", 50000)); using (var reader = await command.ExecuteReaderAsync(cancellationToken)) { var mapper = new LoggingEventResultMapper(reader); // Read the first record to get the total number of events before paging is applied. // This stored procedure uses an optimized CTE query, however, a side effect of // this solution is that the total number of records is presented in each row. if (!reader.Read() || (total = mapper.GetTotal()) <= 0) { return(ListResult <EventResult> .Empty); } do { listBuilder.Add(mapper.Translate()); }while (reader.Read()); } } } finally { connection.Close(); } return(ListResult.Create(listBuilder.ToImmutable(), total)); }