using System.Data; using Housing.Models; using Microsoft.Data.SqlClient; namespace Housing.Services; public sealed class HousingAssemblyRepository { private readonly DatabaseSettings _settings; public HousingAssemblyRepository(DatabaseSettings settings) { _settings = settings; } public async Task InsertHeaderAsync(HousingAssemblyRecord record) { using var connection = new SqlConnection(CreateConnectionString()); using var command = connection.CreateCommand(); command.CommandText = @" INSERT INTO dbo.Housing_Assembly ( [IC_SN], [PCB_Barcode], [Maker], [Model], [Variant_1], [Variant_2], [Operator], [Password], [Production_Date], [Line], [Lot_No], [Jig_No] ) VALUES ( @IC_SN, @PCB_Barcode, @Maker, @Model, @Variant_1, @Variant_2, @Operator, @Password, @Production_Date, @Line, @Lot_No, @Jig_No );"; AddNVarChar(command, "@IC_SN", 50, record.IcSn); AddNVarChar(command, "@PCB_Barcode", 50, record.PcbBarcode); AddNVarChar(command, "@Maker", 10, record.Maker); AddNVarChar(command, "@Model", 10, record.Model); AddNVarChar(command, "@Variant_1", 10, record.Variant1); AddNVarChar(command, "@Variant_2", 10, record.Variant2); AddNVarChar(command, "@Operator", 10, record.Operator); AddNVarChar(command, "@Password", 10, record.Password); command.Parameters.Add(new SqlParameter("@Production_Date", SqlDbType.DateTime2) { Value = record.ProductionDate }); AddNVarChar(command, "@Line", 5, record.Line); AddNVarChar(command, "@Lot_No", 8, record.LotNo); AddNVarChar(command, "@Jig_No", 10, record.JigNo); await connection.OpenAsync(); await command.ExecuteNonQueryAsync(); } public async Task UpsertHeaderAsync(HousingAssemblyRecord record) { using var connection = new SqlConnection(CreateConnectionString()); using var command = connection.CreateCommand(); command.CommandText = @" SET XACT_ABORT ON; BEGIN TRANSACTION; UPDATE dbo.Housing_Assembly WITH (UPDLOCK, HOLDLOCK) SET [PCB_Barcode] = @PCB_Barcode, [Maker] = @Maker, [Model] = @Model, [Variant_1] = @Variant_1, [Variant_2] = @Variant_2, [Operator] = @Operator, [Password] = @Password, [Production_Date] = @Production_Date, [Line] = @Line, [Lot_No] = @Lot_No, [Jig_No] = @Jig_No WHERE [IC_SN] = @IC_SN; IF @@ROWCOUNT = 0 BEGIN INSERT INTO dbo.Housing_Assembly ( [IC_SN], [PCB_Barcode], [Maker], [Model], [Variant_1], [Variant_2], [Operator], [Password], [Production_Date], [Line], [Lot_No], [Jig_No] ) VALUES ( @IC_SN, @PCB_Barcode, @Maker, @Model, @Variant_1, @Variant_2, @Operator, @Password, @Production_Date, @Line, @Lot_No, @Jig_No ); END; COMMIT TRANSACTION;"; AddNVarChar(command, "@IC_SN", 50, record.IcSn); AddNVarChar(command, "@PCB_Barcode", 50, record.PcbBarcode); AddNVarChar(command, "@Maker", 10, record.Maker); AddNVarChar(command, "@Model", 10, record.Model); AddNVarChar(command, "@Variant_1", 10, record.Variant1); AddNVarChar(command, "@Variant_2", 10, record.Variant2); AddNVarChar(command, "@Operator", 10, record.Operator); AddNVarChar(command, "@Password", 10, record.Password); command.Parameters.Add(new SqlParameter("@Production_Date", SqlDbType.DateTime2) { Value = record.ProductionDate }); AddNVarChar(command, "@Line", 5, record.Line); AddNVarChar(command, "@Lot_No", 8, record.LotNo); AddNVarChar(command, "@Jig_No", 10, record.JigNo); await connection.OpenAsync(); await command.ExecuteNonQueryAsync(); } public async Task UpdateMeasurementAsync(HousingAssemblyRecord record) { using var connection = new SqlConnection(CreateConnectionString()); using var command = connection.CreateCommand(); command.CommandText = @" UPDATE dbo.Housing_Assembly SET [PT_Vol_1] = @PT_Vol_1, [PT_Current_1] = @PT_Current_1, [Result] = @Result, [Spare_1] = @Spare_1, [Spare_2] = @Spare_2, [Spare_3] = @Spare_3, [Spare_4] = @Spare_4 WHERE [IC_SN] = @IC_SN;"; AddNVarChar(command, "@IC_SN", 50, record.IcSn); AddDecimal(command, "@PT_Vol_1", record.PtVol1); AddDecimal(command, "@PT_Current_1", record.PtCurrent1); AddNVarChar(command, "@Result", 5, record.Result); AddNullableNVarChar(command, "@Spare_1", 30, record.Spare1); AddNullableNVarChar(command, "@Spare_2", 30, record.Spare2); AddNullableNVarChar(command, "@Spare_3", 30, record.Spare3); AddNullableNVarChar(command, "@Spare_4", 30, record.Spare4); await connection.OpenAsync(); var affectedRows = await command.ExecuteNonQueryAsync(); if (affectedRows == 0) { throw new InvalidOperationException("DB measurement update target was not found."); } } public async Task InsertAsync(HousingAssemblyRecord record) { await UpsertHeaderAsync(record); await UpdateMeasurementAsync(record); } private string CreateConnectionString() { if (string.IsNullOrWhiteSpace(_settings.Ip) || string.IsNullOrWhiteSpace(_settings.Database) || string.IsNullOrWhiteSpace(_settings.DbId)) { throw new InvalidOperationException("Database.ini의 IP, Database, DbId 값을 확인하세요."); } var builder = new SqlConnectionStringBuilder { DataSource = _settings.Ip, InitialCatalog = _settings.Database, UserID = _settings.DbId, Password = _settings.DbPw, Encrypt = _settings.Encrypt, TrustServerCertificate = _settings.TrustServerCertificate, ConnectTimeout = _settings.Timeout }; return builder.ConnectionString; } private static void AddNVarChar(SqlCommand command, string name, int size, string value) { command.Parameters.Add(new SqlParameter(name, SqlDbType.NVarChar, size) { Value = value }); } private static void AddNullableNVarChar(SqlCommand command, string name, int size, string? value) { command.Parameters.Add(new SqlParameter(name, SqlDbType.NVarChar, size) { Value = string.IsNullOrWhiteSpace(value) ? DBNull.Value : value }); } private static void AddDecimal(SqlCommand command, string name, decimal value) { var parameter = new SqlParameter(name, SqlDbType.Decimal) { Precision = 3, Scale = 2, Value = value }; command.Parameters.Add(parameter); } }