улучшения 2 и 3

This commit is contained in:
mara-1 2024-12-24 21:26:31 +04:00
parent dfb8ee759f
commit 20215be662
19 changed files with 205 additions and 59 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,10 +10,21 @@ namespace ProjectHorseRacingOrg.Entities;
public class Horse public class Horse
{ {
public int Id { get; private set; } public int Id { get; private set; }
[DisplayName("Вид")]
public string HorseSpecies { get; private set; } = string.Empty; public string HorseSpecies { get; private set; } = string.Empty;
[DisplayName("Кличка")]
public string HorseNickName { get; private set; } = string.Empty; public string HorseNickName { get; private set; } = string.Empty;
public string FullName => $"{HorseSpecies} {HorseNickName}";
[DisplayName("Возраст")]
public int Age { get; private set; } public int Age { get; private set; }
[DisplayName("Вес")]
public double Weight { get; private set; } public double Weight { get; private set; }
public static Horse CreateEntity(int id, string horseSpecies, string public static Horse CreateEntity(int id, string horseSpecies, string
horseNickName, int age, double weight) horseNickName, int age, double weight)
{ {

View File

@ -1,6 +1,7 @@
using ProjectHorseRacingOrg.Entities.Enums; using ProjectHorseRacingOrg.Entities.Enums;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -10,9 +11,18 @@ namespace ProjectHorseRacingOrg.Entities;
public class Jockey public class Jockey
{ {
public int Id { get; private set; } public int Id { get; private set; }
[DisplayName("Имя")]
public string FirstName { get; private set; } = string.Empty; public string FirstName { get; private set; } = string.Empty;
[DisplayName("Фамилия")]
public string LastName { get; private set; } = string.Empty; public string LastName { get; private set; } = string.Empty;
public string FullName => $"{LastName} {FirstName}";
[DisplayName("Титул")]
public JockeyTitle JockeyTitle { get; private set; } public JockeyTitle JockeyTitle { get; private set; }
public static Jockey CreateEntity(int id, string first, string last, public static Jockey CreateEntity(int id, string first, string last,
JockeyTitle jockeyTitle) JockeyTitle jockeyTitle)
{ {

View File

@ -2,6 +2,7 @@
using ProjectHorseRacingOrg.Entities.Enums; using ProjectHorseRacingOrg.Entities.Enums;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -11,11 +12,17 @@ namespace ProjectHorseRacingOrg.Entities;
public class Race public class Race
{ {
public int Id { get; private set; } public int Id { get; private set; }
[DisplayName("Тип соревнований")]
public RaceType RaceType { get; private set; } public RaceType RaceType { get; private set; }
[DisplayName("Название")]
public string Name { get; private set; } = string.Empty; public string Name { get; private set; } = string.Empty;
[DisplayName("Описание")]
public string Description { get; private set; } = string.Empty; public string Description { get; private set; } = string.Empty;
public static Race CreateEntity(int id, RaceType raceType, string name,
string description) public static Race CreateEntity(int id, RaceType raceType, string name, string description)
{ {
return new Race return new Race
{ {

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,11 +10,24 @@ namespace ProjectHorseRacingOrg.Entities;
public class RaceEntries public class RaceEntries
{ {
public int Id { get; private set; } public int Id { get; private set; }
[Browsable(false)]
public int JockeyId { get; private set; } public int JockeyId { get; private set; }
[DisplayName("Жокей")]
public string JockeyName { get; private set; } = string.Empty;
[DisplayName("Дата соревнований")]
public DateTime DateReceipt { get; private set; } public DateTime DateReceipt { get; private set; }
[DisplayName("Соревнования")]
public string Feed => RacesEntryDetails != null ?
string.Join(", ", RacesEntryDetails.Select(x => $"{x.RaceName} {x.Count}")) : string.Empty;
[Browsable(false)]
public IEnumerable<RaceEntryDetails> RacesEntryDetails { get; private set;} = []; public IEnumerable<RaceEntryDetails> RacesEntryDetails { get; private set;} = [];
public static RaceEntries CreateOpeartion(int id, int jockeyId, public static RaceEntries CreateOpeartion(int id, int jockeyId,
IEnumerable<RaceEntryDetails> racesEntryDetails) IEnumerable<RaceEntryDetails> racesEntryDetails)
{ {
@ -26,16 +40,12 @@ public class RaceEntries
}; };
} }
public static RaceEntries CreateOpeartion(TempRaceEntryDetails tempRaceEntryDetails, public void SetRacesEntryDetails(IEnumerable<RaceEntryDetails> racesEntryDetails)
IEnumerable<RaceEntryDetails> racesEntryDetails)
{ {
return new RaceEntries if (racesEntryDetails != null && racesEntryDetails.Any())
{ {
Id = tempRaceEntryDetails.Id, RacesEntryDetails = racesEntryDetails;
JockeyId = tempRaceEntryDetails.JockeyId, }
DateReceipt = tempRaceEntryDetails.DateReceipt,
RacesEntryDetails = racesEntryDetails
};
} }

View File

@ -11,6 +11,7 @@ public class RaceEntryDetails
public int Id { get; private set; } public int Id { get; private set; }
public int RaceId { get; private set; } public int RaceId { get; private set; }
public int Count { get; private set; } public int Count { get; private set; }
public string RaceName { get; private set; } = string.Empty;
public static RaceEntryDetails CreateElement(int id, int raceId, int public static RaceEntryDetails CreateElement(int id, int raceId, int
count) count)
{ {

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,11 +10,31 @@ namespace ProjectHorseRacingOrg.Entities;
public class RacingHorses public class RacingHorses
{ {
public int Id { get; private set; } public int Id { get; private set; }
[Browsable(false)]
public int RaceId { get; private set; } public int RaceId { get; private set; }
[Browsable(false)]
public int JockeyId { get; private set; } public int JockeyId { get; private set; }
[Browsable(false)]
public int HorseId { get; private set; } public int HorseId { get; private set; }
[DisplayName("Соревнование")]
public string RaceName { get; private set; } = string.Empty;
[DisplayName("Жокей")]
public string JockeyName { get; private set; } = string.Empty;
[DisplayName("Лошадь")]
public string HorseName { get; private set; } = string.Empty;
[DisplayName("Дата соревнования")]
public DateTime RacingDate { get; private set; } public DateTime RacingDate { get; private set; }
[DisplayName("результаты место")]
public int Result { get; private set; } public int Result { get; private set; }
public static RacingHorses CreateOpeartion(int id, int raceId, int public static RacingHorses CreateOpeartion(int id, int raceId, int
jockeyId, int horseId, int result) jockeyId, int horseId, int result)
{ {

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectHorseRacingOrg.Entities;
public class TempRaceEntryDetails
{
public int Id { get; private set; }
public int JockeyId { get; private set; }
public DateTime DateReceipt { get; private set; }
public int RaceId { get; private set; }
public int Count { get; private set; }
}

View File

@ -95,7 +95,12 @@ namespace ProjectHorseRacingOrg.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void LoadList() => dataGridViewData.DataSource = _horseRepository.ReadHorses(); private void LoadList()
{
dataGridViewData.DataSource = _horseRepository.ReadHorses();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {
id = 0; id = 0;

View File

@ -94,8 +94,11 @@ private void ButtonUpd_Click(object sender, EventArgs e)
MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void LoadList() => dataGridViewData.DataSource = private void LoadList()
_jockeyRepository.ReadJockeys(); {
dataGridViewData.DataSource = _jockeyRepository.ReadJockeys();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {
id = 0; id = 0;

View File

@ -27,7 +27,7 @@ namespace ProjectHorseRacingOrg.Forms
throw new throw new
ArgumentNullException(nameof(raceEntriesRepository)); ArgumentNullException(nameof(raceEntriesRepository));
comboBoxJockey.DataSource = jockeyRepository.ReadJockeys(); comboBoxJockey.DataSource = jockeyRepository.ReadJockeys();
comboBoxJockey.DisplayMember = "FirstName"; comboBoxJockey.DisplayMember = "FullName";
comboBoxJockey.ValueMember = "Id"; comboBoxJockey.ValueMember = "Id";
ColumnRace.DataSource = raceRepository.ReadRaces(); ColumnRace.DataSource = raceRepository.ReadRaces();
ColumnRace.DisplayMember = "Name"; ColumnRace.DisplayMember = "Name";

View File

@ -92,7 +92,12 @@ namespace ProjectHorseRacingOrg.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void LoadList() => dataGridViewData.DataSource = _raceRepository.ReadRaces(); private void LoadList()
{
dataGridViewData.DataSource = _raceRepository.ReadRaces();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -75,8 +75,11 @@ namespace ProjectHorseRacingOrg.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void LoadList() => dataGridViewData.DataSource = private void LoadList()
_raceEntriesRepository.ReadRaceEntries(); {
dataGridViewData.DataSource = _raceEntriesRepository.ReadRaceEntries();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {
id = 0; id = 0;

View File

@ -28,13 +28,13 @@ namespace ProjectHorseRacingOrg.Forms
throw new throw new
ArgumentNullException(nameof(racingHorsesRepository)); ArgumentNullException(nameof(racingHorsesRepository));
comboBoxJockey.DataSource = jockeyRepository.ReadJockeys(); comboBoxJockey.DataSource = jockeyRepository.ReadJockeys();
comboBoxJockey.DisplayMember = "FirstName"; comboBoxJockey.DisplayMember = "FullName";
comboBoxJockey.ValueMember = "Id"; comboBoxJockey.ValueMember = "Id";
comboBoxRace.DataSource = raceRepository.ReadRaces(); comboBoxRace.DataSource = raceRepository.ReadRaces();
comboBoxRace.DisplayMember = "Name"; comboBoxRace.DisplayMember = "Name";
comboBoxRace.ValueMember = "Id"; comboBoxRace.ValueMember = "Id";
comboBoxHorse.DataSource = horseRepository.ReadHorses(); comboBoxHorse.DataSource = horseRepository.ReadHorses();
comboBoxHorse.DisplayMember = "HorseNickName"; comboBoxHorse.DisplayMember = "FullName";
comboBoxHorse.ValueMember = "Id"; comboBoxHorse.ValueMember = "Id";
} }
private void ButtonSave_Click(object sender, EventArgs e) private void ButtonSave_Click(object sender, EventArgs e)

View File

@ -52,8 +52,11 @@ namespace ProjectHorseRacingOrg.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void LoadList() => dataGridViewData.DataSource = private void LoadList()
_racingHorsesRepository.ReadRacingHorses(); {
dataGridViewData.DataSource = _racingHorsesRepository.ReadRacingHorses();
dataGridViewData.Columns["Id"].Visible = false;
}
} }
} }

View File

@ -28,7 +28,7 @@ public class ChartReport
{ {
new PdfBuilder(filePath) new PdfBuilder(filePath)
.AddHeader("Участие лошадей") .AddHeader("Участие лошадей")
.AddPieChart("Состоявшиеся соревнования", GetData(dateTime)) .AddPieChart($"Состоявшиеся соревнования на {dateTime:dd MMMM yyyy}", GetData(dateTime))
.Build(); .Build();
return true; return true;
} }
@ -43,11 +43,11 @@ public class ChartReport
return _racingHorsesRepository return _racingHorsesRepository
.ReadRacingHorses() .ReadRacingHorses()
.Where(x => x.RacingDate.Date == dateTime.Date) .Where(x => x.RacingDate.Date == dateTime.Date)
.GroupBy(x => x.HorseId, (key, group) => new { .GroupBy(x => x.HorseName, (key, group) => new {
Id = key, Name = key,
Count = group.Sum(x => x.Result) Count = group.Sum(x => x.Result)
}) })
.Select(x => (x.Id.ToString(), (double)x.Count)) .Select(x => (x.Name, (double)x.Count))
.ToList(); .ToList();
} }
} }

View File

@ -33,7 +33,7 @@ internal class TableReport
{ {
new ExcelBuilder(filePath) new ExcelBuilder(filePath)
.AddHeader("Сводка по движению соревнований", 0, 4) .AddHeader("Сводка по движению соревнований", 0, 4)
.AddParagraph("за период", 0) .AddParagraph($"за период c {startDate:dd.MM.yyyy} по {endDate: dd.MM.yyyy}", 0)
.AddTable([10, 10, 15, 15], GetData(raceId, startDate, endDate)) .AddTable([10, 10, 15, 15], GetData(raceId, startDate, endDate))
.Build(); .Build();
return true; return true;
@ -49,19 +49,19 @@ internal class TableReport
var data = _raceEntriesRepository var data = _raceEntriesRepository
.ReadRaceEntries() .ReadRaceEntries()
.Where(x => x.DateReceipt >= startDate && x.DateReceipt <= endDate && x.RacesEntryDetails.Any(y => y.RaceId == raceId)) .Where(x => x.DateReceipt >= startDate && x.DateReceipt <= endDate && x.RacesEntryDetails.Any(y => y.RaceId == raceId))
.Select(x => new { x.JockeyId, Date = x.DateReceipt, CountIn = x.RacesEntryDetails.FirstOrDefault(y => y.RaceId == raceId)?.Count, CountOut = (int?)null }) .Select(x => new { x.JockeyName, Date = x.DateReceipt, CountIn = x.RacesEntryDetails.FirstOrDefault(y => y.RaceId == raceId)?.Count, CountOut = (int?)null })
.Union( .Union(
_racingHorsesRepository _racingHorsesRepository
.ReadRacingHorses() .ReadRacingHorses()
.Where(x => x.RacingDate >= startDate && x.RacingDate <= endDate && x.RaceId == raceId) .Where(x => x.RacingDate >= startDate && x.RacingDate <= endDate && x.RaceId == raceId)
.Select(x => new { x.JockeyId, Date = x.RacingDate, CountIn = (int?)null, CountOut = (int?)x.Result })) .Select(x => new { x.JockeyName, Date = x.RacingDate, CountIn = (int?)null, CountOut = (int?)x.Result }))
.OrderBy(x => x.Date); .OrderBy(x => x.Date);
return return
new List<string[]>() { item } new List<string[]>() { item }
.Union( .Union(
data data
.Select(x => new string[] { x.JockeyId.ToString(), x.Date.ToString(), x.CountIn?.ToString() ?? string.Empty, x.CountOut?.ToString() ?? string.Empty})) .Select(x => new string[] { x.JockeyName, x.Date.ToString(), x.CountIn?.ToString() ?? string.Empty, x.CountOut?.ToString() ?? string.Empty}))
.Union( .Union(
[["Всего", "", data.Sum(x => x.CountIn ?? 0).ToString(), data.Sum(x => x.CountOut ?? 0).ToString()]]) [["Всего", "", data.Sum(x => x.CountIn ?? 0).ToString(), data.Sum(x => x.CountOut ?? 0).ToString()]])

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectHorseRacingOrg.Repositories.Implementations;
public class QueryBuilder
{
private readonly StringBuilder _builder;
public QueryBuilder()
{
_builder = new();
}
public QueryBuilder AddCondition(string condition)
{
if (_builder.Length > 0)
{
_builder.Append(" AND ");
}
_builder.Append(condition);
return this;
}
public string Build()
{
if (_builder.Length == 0)
{
return string.Empty;
}
return $"WHERE {_builder}";
}
}

View File

@ -88,24 +88,63 @@ WHERE Id=@id";
_logger.LogInformation("Получение всех объектов"); _logger.LogInformation("Получение всех объектов");
try try
{ {
var builder = new QueryBuilder();
if (dateForm.HasValue)
{
builder.AddCondition("re.DateReceipt >= @dateForm");
}
if (dateTo.HasValue)
{
builder.AddCondition("re.DateReceipt <= @dateTo");
}
if (raceId.HasValue)
{
builder.AddCondition("re.RaceId = @raceId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString); using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @" var querySelect = @$"
SELECT fr.*, ffr.RaceId, ffr.Count FROM RaceEntries fr SELECT
INNER JOIN RaceEntryDetails ffr ON ffr.RaceEntryId = fr.Id"; re.*,
CONCAT(j.LastName, ' ', j.FirstName) as JockeyName,
red.RaceId,
red.Count,
r.Name as RaceName
FROM RaceEntries re
LEFT JOIN Jockeys j ON j.Id = re.JockeyId
INNER JOIN RaceEntryDetails red ON red.RaceEntryId = re.Id
LEFT JOIN Races r ON r.Id = red.RaceId
{builder.Build()}";
var racesEntries = connection.Query<TempRaceEntryDetails>(querySelect); var raceEntryDict = new Dictionary<int, List<RaceEntryDetails>>();
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(racesEntries));
return racesEntries.GroupBy(x => x.Id, y => y, var raceEntries = connection.Query<RaceEntries, RaceEntryDetails, RaceEntries>(querySelect,
(key, value) => (entry, details) =>
RaceEntries.CreateOpeartion(value.First(), {
value.Select(z => if (!raceEntryDict.TryGetValue(entry.Id, out var red))
RaceEntryDetails.CreateElement(0, z.RaceId, z.Count)))).ToList(); {
red = new List<RaceEntryDetails>();
raceEntryDict.Add(entry.Id, red);
}
red.Add(details);
return entry;
}, splitOn: "RaceId", param: new { dateForm, dateTo, raceId });
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(raceEntries));
return raceEntryDict.Select(x =>
{
var re = raceEntries.First(y => y.Id == x.Key);
re.SetRacesEntryDetails(x.Value);
return re;
}).ToArray();
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка при чтении объектов"); _logger.LogError(ex, "Ошибка при чтении объектов");
throw; throw;
} }
} }
} }

View File

@ -50,7 +50,11 @@ VALUES (@RaceId, @JockeyId, @HorseId, @RacingDate, @Result)";
{ {
using var connection = new using var connection = new
NpgsqlConnection(_connectionString.ConnectionString); NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM RacingHorses"; var querySelect = @"select rh.*, r.RaceType as RaceName, CONCAT(j.LastName, ' ', j.FirstName) as JockeyName, h.HorseNickName as HorseName
from racingHorses rh
INNER JOIN Races r ON r.Id = rh.RaceId
INNER JOIN Jockeys j ON j.Id = rh.JockeyId
INNER JOIN Horses h ON h.Id = rh.HorseId";
var racingHorses = var racingHorses =
connection.Query<RacingHorses>(querySelect); connection.Query<RacingHorses>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", _logger.LogDebug("Полученные объекты: {json}",