Allineamento dati con repository di origine

This commit is contained in:
2025-08-17 23:40:09 +02:00
parent 93f3d02f32
commit f767fe6e35
55 changed files with 48638 additions and 0 deletions

View File

@@ -0,0 +1,198 @@
using System;
using System.Data.SqlClient;
using System.Text.Json.Nodes;
namespace HorseRacingPredictor.Football.Database
{
internal class Odds : HorseRacingPredictor.Football.Manager.Database
{
public void Upsert(SqlConnection connection, JsonNode bookmakers, int fixtureId)
{
try
{
// Aggiungiamo log per tracciare la struttura dei dati
LogError($"Inizio elaborazione quote per fixture {fixtureId} con {bookmakers?.AsArray().Count ?? 0} bookmakers", null);
// Per ogni bookmaker
foreach (var bookmaker in bookmakers.AsArray())
{
int bookmakerId = bookmaker["id"].GetValue<int>();
var bets = bookmaker["bets"];
// Cerchiamo le quote di tipo Match Winner (1X2)
foreach (var bet in bets.AsArray())
{
// Gestiamo in modo più sicuro il recupero di valori dal JSON
string betName = GetStringValueSafe(bet, "name");
// Log per debug
LogError($"Elaborazione bet: '{betName}' per bookmaker {bookmakerId}", null);
// Determina il tipo di scommessa (assumiamo che esista una tabella BetType)
int betTypeId = GetBetTypeId(connection, betName);
// Se non riusciamo a determinare il tipo di scommessa, continuiamo con la prossima
if (betTypeId == 0) continue;
// Estrai e salva le quote
foreach (var value in bet["values"].AsArray())
{
// Gestiamo in modo più sicuro il recupero di valori dal JSON
string valueType = GetStringValueSafe(value, "value");
decimal oddValue = GetDecimalValueSafe(value, "odd");
// Log per debug
LogError($"Elaborazione quota: tipo={valueType}, valore={oddValue}", null);
if (oddValue > 0) // Verifichiamo che il valore sia valido
{
var query = @"
IF EXISTS (SELECT 1 FROM Odd WHERE fixture_id = @fixture_id AND bookmaker_id = @bookmaker_id
AND bet_type_id = @bet_type_id AND value = @value)
BEGIN
UPDATE Odd
SET odd = @odd, update_time = @update_time
WHERE fixture_id = @fixture_id AND bookmaker_id = @bookmaker_id
AND bet_type_id = @bet_type_id AND value = @value
END
ELSE
BEGIN
INSERT INTO Odd (fixture_id, bookmaker_id, bet_type_id, value, odd, update_time)
VALUES (@fixture_id, @bookmaker_id, @bet_type_id, @value, @odd, @update_time)
END";
using (var command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("@fixture_id", fixtureId);
command.Parameters.AddWithValue("@bookmaker_id", bookmakerId);
command.Parameters.AddWithValue("@bet_type_id", betTypeId);
command.Parameters.AddWithValue("@value", valueType);
command.Parameters.AddWithValue("@odd", oddValue);
command.Parameters.AddWithValue("@update_time", DateTime.Now);
command.ExecuteNonQuery();
}
}
}
}
}
}
catch (Exception ex)
{
LogError("l'upsert delle quote", ex);
}
}
/// <summary>
/// Ottiene l'ID del tipo di scommessa in base al nome
/// </summary>
private int GetBetTypeId(SqlConnection connection, string betTypeName)
{
try
{
// Prima verifica se il tipo di scommessa esiste
var queryCheck = "SELECT bet_type_id FROM BetType WHERE name = @name";
using (var command = new SqlCommand(queryCheck, connection))
{
command.Parameters.AddWithValue("@name", betTypeName);
var result = command.ExecuteScalar();
if (result != null && result != DBNull.Value)
{
return Convert.ToInt32(result);
}
else
{
// Se non esiste, inseriscilo (con un ID progressivo)
var queryInsert = @"
DECLARE @next_id INT;
SELECT @next_id = ISNULL(MAX(bet_type_id), 0) + 1 FROM BetType;
INSERT INTO BetType (bet_type_id, name)
VALUES (@next_id, @name);
SELECT @next_id;";
using (var insertCommand = new SqlCommand(queryInsert, connection))
{
insertCommand.Parameters.AddWithValue("@name", betTypeName);
return Convert.ToInt32(insertCommand.ExecuteScalar());
}
}
}
}
catch (Exception ex)
{
LogError($"determinazione bet_type_id per '{betTypeName}'", ex);
return 0;
}
}
/// <summary>
/// Ottiene un valore stringa da un JsonNode in modo sicuro
/// </summary>
private string GetStringValueSafe(JsonNode node, string propertyName)
{
try
{
if (node == null || node[propertyName] == null)
return string.Empty;
var value = node[propertyName];
// Gestiamo diversi tipi di nodi
if (value.GetValueKind() == System.Text.Json.JsonValueKind.String)
return value.GetValue<string>();
else if (value.GetValueKind() == System.Text.Json.JsonValueKind.Number)
return value.GetValue<decimal>().ToString();
else
return value.ToString();
}
catch (Exception ex)
{
LogError($"estrazione valore stringa per proprietà '{propertyName}'", ex);
return string.Empty;
}
}
/// <summary>
/// Ottiene un valore decimale da un JsonNode in modo sicuro
/// </summary>
private decimal GetDecimalValueSafe(JsonNode node, string propertyName)
{
try
{
if (node == null || node[propertyName] == null)
return 0;
var value = node[propertyName];
// Gestiamo diversi tipi di nodi
if (value.GetValueKind() == System.Text.Json.JsonValueKind.Number)
{
// Assicuriamoci che il valore sia esattamente quello originale
return value.GetValue<decimal>();
}
else if (value.GetValueKind() == System.Text.Json.JsonValueKind.String)
{
// Utilizziamo InvariantCulture per garantire una corretta interpretazione dei decimali
if (decimal.TryParse(value.GetValue<string>(),
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture,
out decimal result))
{
return result;
}
}
// Aggiungiamo un log più dettagliato per aiutare il debug
LogError($"Impossibile convertire '{value}' (tipo: {value.GetValueKind()}) in decimal per proprietà '{propertyName}'", null);
return 0;
}
catch (Exception ex)
{
LogError($"estrazione valore decimal per proprietà '{propertyName}'", ex);
return 0;
}
}
}
}