InfinityQS
This commit is contained in:
151
Server/Repositories/IInfinityQSRepository.cs
Normal file
151
Server/Repositories/IInfinityQSRepository.cs
Normal file
@ -0,0 +1,151 @@
|
||||
using OI.Metrology.Shared.DataModels;
|
||||
using OI.Metrology.Shared.Models.Stateless;
|
||||
using OI.Metrology.Shared.Repositories;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace OI.Metrology.Server.Repository;
|
||||
|
||||
public class InfinityQSRepository : IInfinityQSRepository
|
||||
{
|
||||
|
||||
private readonly IDbConnectionFactory _DBConnectionFactory;
|
||||
|
||||
public InfinityQSRepository(IDbConnectionFactory dbConnectionFactory) => _DBConnectionFactory = dbConnectionFactory;
|
||||
|
||||
string IInfinityQSRepository.GetCommandText(string? subGroupId, string? process, string? job, string? part, string? lot, string? dateTime)
|
||||
{
|
||||
StringBuilder result = new();
|
||||
const string dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':')) && dateTime.Length != dateTimeFormat.Length)
|
||||
throw new ArgumentException(nameof(dateTime));
|
||||
_ = result
|
||||
.AppendLine(" select ")
|
||||
.AppendLine(" se.f_sgrp se_sgrp, ")
|
||||
.AppendLine(" se.f_sgtm se_sgtm, ")
|
||||
.AppendLine(" se.f_tsno se_tsno, ")
|
||||
.AppendLine(" se.f_val se_val, ")
|
||||
.AppendLine(" rd.f_name rd_name, ")
|
||||
.AppendLine(" jd.f_name jd_name, ")
|
||||
.AppendLine(" pl.f_name pl_name, ")
|
||||
.AppendLine(" pd.f_name pd_name, ")
|
||||
.AppendLine(" td.f_test td_test, ")
|
||||
.AppendLine(" td.f_name td_name, ")
|
||||
.AppendLine(" (select count(ev.f_evnt) ")
|
||||
.AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
|
||||
.AppendLine(" where ev.f_prcs = rd.f_prcs ")
|
||||
.AppendLine(" and ev.f_part = pd.f_part ")
|
||||
.AppendLine(" and ev.f_sgtm = se.f_sgtm) ev_count ")
|
||||
.AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ")
|
||||
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] rd ")
|
||||
.AppendLine(" on se.f_prcs = rd.f_prcs ")
|
||||
.AppendLine(" join [spcepiworld].[dbo].[job_dat] jd ")
|
||||
.AppendLine(" on se.f_job = jd.f_job ")
|
||||
.AppendLine(" join [spcepiworld].[dbo].[part_lot] pl ")
|
||||
.AppendLine(" on se.f_lot = pl.f_lot ")
|
||||
.AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
|
||||
.AppendLine(" on se.f_part = pd.f_part ")
|
||||
.AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
|
||||
.AppendLine(" on se.f_test = td.f_test ")
|
||||
.AppendLine(" where se.f_flag = 0 ");
|
||||
if (!string.IsNullOrEmpty(subGroupId))
|
||||
_ = result.Append(" and se.f_sgrp = ").Append(subGroupId.Split(" ")[0]).AppendLine(" ");
|
||||
if (!string.IsNullOrEmpty(process))
|
||||
_ = result.Append(" and rd.f_name = '").Append(process).AppendLine("' ");
|
||||
if (!string.IsNullOrEmpty(part))
|
||||
_ = result.Append(" and pd.f_name = '").Append(part).AppendLine("' ");
|
||||
if (!string.IsNullOrEmpty(job))
|
||||
_ = result.Append(" and jd.f_name = '").Append(job).AppendLine("' ");
|
||||
if (!string.IsNullOrEmpty(lot))
|
||||
_ = result.Append(" and pl.f_name = '").Append(lot).AppendLine("' ");
|
||||
if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':')))
|
||||
_ = result.Append(" and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '").Append(dateTime).AppendLine("' ");
|
||||
_ = result.AppendLine(" for json path ");
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
private static StringBuilder GetForJsonPath(IDbConnectionFactory dbConnectionFactory, string commandText)
|
||||
{
|
||||
StringBuilder stringBuilder = new();
|
||||
using DbConnection dbConnection = dbConnectionFactory.GetDbConnection();
|
||||
DbCommand dbCommand = dbConnection.CreateCommand();
|
||||
dbCommand.CommandText = commandText;
|
||||
DbDataReader dbDataReader = dbCommand.ExecuteReader(CommandBehavior.SequentialAccess);
|
||||
while (dbDataReader.Read())
|
||||
_ = stringBuilder.Append(dbDataReader.GetString(0));
|
||||
return stringBuilder;
|
||||
}
|
||||
|
||||
private static InfinityQSBase GetInfinityQSBase(IDbConnectionFactory dbConnectionFactory, IInfinityQSRepository infinityQSRepository, string subGroupId)
|
||||
{
|
||||
InfinityQSBase result;
|
||||
string commandText = infinityQSRepository.GetCommandText(subGroupId, process: string.Empty, job: string.Empty, part: string.Empty, lot: string.Empty, dateTime: string.Empty);
|
||||
StringBuilder stringBuilder = GetForJsonPath(dbConnectionFactory, commandText);
|
||||
InfinityQSBase[]? results = JsonSerializer.Deserialize<InfinityQSBase[]>(stringBuilder.ToString());
|
||||
if (results is null)
|
||||
throw new NullReferenceException(nameof(results));
|
||||
if (results.Select(l => l.SubGroupId).Distinct().Count() != 1)
|
||||
throw new NotSupportedException("Multiple ids are present!");
|
||||
result = results.First();
|
||||
return result;
|
||||
}
|
||||
|
||||
Result<InfinityQSBase[]> IInfinityQSRepository.GetData(string subGroupId)
|
||||
{
|
||||
Result<InfinityQSBase[]>? result;
|
||||
IInfinityQSRepository infinityQSRepository = this;
|
||||
InfinityQSBase infinityQSBase = GetInfinityQSBase(_DBConnectionFactory, infinityQSRepository, subGroupId);
|
||||
string commandText = infinityQSRepository.GetCommandText(subGroupId, process: infinityQSBase.Process, job: infinityQSBase.Job, part: infinityQSBase.Part, lot: infinityQSBase.Lot, dateTime: string.Concat(infinityQSBase.SubGroupDateTime));
|
||||
StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText);
|
||||
InfinityQSBase[]? results = JsonSerializer.Deserialize<InfinityQSBase[]>(stringBuilder.ToString());
|
||||
if (results is null)
|
||||
throw new NullReferenceException(nameof(results));
|
||||
result = new()
|
||||
{
|
||||
Results = results,
|
||||
TotalRows = results.Length,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
Result<InfinityQSEvent[]> IInfinityQSRepository.GetEvents(string subGroupId)
|
||||
{
|
||||
Result<InfinityQSEvent[]>? result;
|
||||
IInfinityQSRepository infinityQSRepository = this;
|
||||
InfinityQSEvent[]? results;
|
||||
InfinityQSBase infinityQSBase = GetInfinityQSBase(_DBConnectionFactory, infinityQSRepository, subGroupId);
|
||||
if (!infinityQSBase.EventCount.HasValue || infinityQSBase.EventCount.Value <= 0)
|
||||
results = Array.Empty<InfinityQSEvent>();
|
||||
else
|
||||
{
|
||||
string commandText = $"select * from [spcepiworld].[dbo].[evnt_inf] ev where ev.f_prcs = '{infinityQSBase.Process}' and ev.f_part = '{infinityQSBase.Part}' and ev.f_sgtm = {infinityQSBase.SubGroupDateTime} ";
|
||||
StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText);
|
||||
results = JsonSerializer.Deserialize<InfinityQSEvent[]>(stringBuilder.ToString());
|
||||
if (results is null)
|
||||
throw new NullReferenceException(nameof(results));
|
||||
}
|
||||
result = new()
|
||||
{
|
||||
Results = results,
|
||||
TotalRows = results.Length,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
Result<InfinityQSBase[]> IInfinityQSRepository.GetHeader(string subGroupId)
|
||||
{
|
||||
Result<InfinityQSBase[]>? result;
|
||||
IInfinityQSRepository infinityQSRepository = this;
|
||||
InfinityQSBase infinityQSBase = GetInfinityQSBase(_DBConnectionFactory, infinityQSRepository, subGroupId);
|
||||
InfinityQSBase[] results = new InfinityQSBase[] { infinityQSBase };
|
||||
result = new()
|
||||
{
|
||||
Results = results,
|
||||
TotalRows = results.Length,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -17,18 +17,16 @@ namespace OI.Metrology.Server.Repositories;
|
||||
public class MetrologyRepository : IMetrologyRepository
|
||||
{
|
||||
private readonly string _MockRoot;
|
||||
private readonly IMemoryCache _Cache;
|
||||
private readonly IMemoryCache _MemoryCache;
|
||||
private readonly IDbConnectionFactory _DBConnectionFactory;
|
||||
|
||||
public MetrologyRepository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory, IMemoryCache memoryCache)
|
||||
{
|
||||
_Cache = memoryCache;
|
||||
_MemoryCache = memoryCache;
|
||||
_MockRoot = appSettings.MockRoot;
|
||||
_DBConnectionFactory = dbConnectionFactory;
|
||||
}
|
||||
|
||||
private DbConnection GetDbConnection() => _DBConnectionFactory.GetDbConnection();
|
||||
|
||||
protected DbProviderFactory GetDbProviderFactory(IDbConnection conn) =>
|
||||
DbProviderFactories.GetFactory(conn.GetType().Namespace);
|
||||
|
||||
@ -38,17 +36,17 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("CacheItem: " + key);
|
||||
|
||||
_ = _Cache.Set(key, v, new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromHours(1)));
|
||||
_ = _MemoryCache.Set(key, v, new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromHours(1)));
|
||||
}
|
||||
|
||||
internal IEnumerable<ToolType> GetToolTypes()
|
||||
{
|
||||
IEnumerable<ToolType> cached;
|
||||
string cacheKey = "GetToolTypes";
|
||||
if (_Cache.TryGetValue(cacheKey, out cached))
|
||||
if (_MemoryCache.TryGetValue(cacheKey, out cached))
|
||||
return cached;
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
IEnumerable<ToolType> r = conn.Query<ToolType>("SELECT * FROM ToolType");
|
||||
|
||||
CacheItem(cacheKey, r);
|
||||
@ -60,10 +58,10 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
{
|
||||
ToolType cached;
|
||||
string cacheKey = "GetToolTypeByName_" + name;
|
||||
if (_Cache.TryGetValue(cacheKey, out cached))
|
||||
if (_MemoryCache.TryGetValue(cacheKey, out cached))
|
||||
return cached;
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
ToolType r = conn.QueryFirstOrDefault<ToolType>(
|
||||
"SELECT * FROM ToolType WHERE ToolTypeName = @name",
|
||||
new { name });
|
||||
@ -77,10 +75,10 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
{
|
||||
ToolType cached;
|
||||
string cacheKey = "GetToolTypeByID_" + id.ToString();
|
||||
if (_Cache.TryGetValue(cacheKey, out cached))
|
||||
if (_MemoryCache.TryGetValue(cacheKey, out cached))
|
||||
return cached;
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
ToolType r = conn.QueryFirstOrDefault<ToolType>(
|
||||
"SELECT * FROM ToolType WHERE ID = @id",
|
||||
new { id });
|
||||
@ -94,10 +92,10 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
{
|
||||
IEnumerable<ToolTypeMetadata> cached;
|
||||
string cacheKey = "GetToolTypeMetadataByToolTypeID_" + id.ToString();
|
||||
if (_Cache.TryGetValue(cacheKey, out cached))
|
||||
if (_MemoryCache.TryGetValue(cacheKey, out cached))
|
||||
return cached;
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
IEnumerable<ToolTypeMetadata> r = conn.Query<ToolTypeMetadata>(
|
||||
"SELECT * FROM ToolTypeMetadata WHERE ToolTypeID = @id",
|
||||
new { id });
|
||||
@ -110,7 +108,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
internal long InsertToolDataJSON(JToken jsonrow, long headerId, List<ToolTypeMetadata> metaData, string tableName)
|
||||
{
|
||||
long r = -1;
|
||||
using (DbConnection conn = GetDbConnection())
|
||||
using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
|
||||
{
|
||||
bool isHeader = headerId <= 0;
|
||||
|
||||
@ -267,7 +265,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
DataTable dt = new();
|
||||
DateTime endTimeLocal = endTime.ToLocalTime();
|
||||
DateTime startTimeLocal = startTime.ToLocalTime();
|
||||
using (DbConnection conn = GetDbConnection())
|
||||
using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
|
||||
{
|
||||
DbProviderFactory factory = GetDbProviderFactory(conn);
|
||||
|
||||
@ -323,7 +321,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
throw new Exception("Invalid tool type metadata");
|
||||
|
||||
DataTable dt = new();
|
||||
using (DbConnection conn = GetDbConnection())
|
||||
using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
_ = sb.Append(
|
||||
@ -416,7 +414,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
throw new Exception("Invalid tool type metadata");
|
||||
|
||||
DataTable dt = new();
|
||||
using (DbConnection conn = GetDbConnection())
|
||||
using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
_ = sb.Append(
|
||||
@ -506,7 +504,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
if (tt is null)
|
||||
throw new Exception("Invalid tool type ID");
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
string sql =
|
||||
$"UPDATE [{tt.HeaderTableName}] SET AttachmentID = NEWID() WHERE ID = @HeaderID AND AttachmentID IS NULL; " +
|
||||
$"SELECT AttachmentID FROM [{tt.HeaderTableName}] WHERE ID = @HeaderID";
|
||||
@ -518,14 +516,14 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
if (tt is null)
|
||||
throw new Exception("Invalid tool type ID");
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
string sql =
|
||||
$"SELECT CONVERT(varchar, case when [InsertDate] < [Date] or [Date] is null then [InsertDate] else [Date] end, 120) d FROM[{tt.HeaderTableName}] where ID = @HeaderID";
|
||||
return conn.ExecuteScalar<string>(sql, param: new { HeaderID = headerId });
|
||||
}
|
||||
internal string GetAttachmentInsertDateByGUID(string tableName, Guid attachmentId)
|
||||
{
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
string sql = "";
|
||||
if (tableName is "SP1RunData" or "TencorRunData")
|
||||
{
|
||||
@ -540,7 +538,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
}
|
||||
internal void SetHeaderDirName(string tableName, long headerId, string dateDir)
|
||||
{
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
_ = conn.Execute($"UPDATE [{tableName}] SET AttachDirName = @AttachDirName WHERE ID = @HeaderID;", new { HeaderID = headerId, AttachDirName = dateDir });
|
||||
}
|
||||
|
||||
@ -550,7 +548,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
if (tt is null)
|
||||
throw new Exception("Invalid tool type ID");
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
string sql =
|
||||
$"UPDATE [{tt.DataTableName}] SET AttachmentID = NEWID() WHERE HeaderID = @HeaderID AND Title = @Title AND AttachmentID IS NULL; " +
|
||||
$"SELECT AttachmentID FROM [{tt.DataTableName}] WHERE HeaderID = @HeaderID AND Title = @Title";
|
||||
@ -563,7 +561,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
if (tt is null)
|
||||
throw new Exception("Invalid tool type ID");
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
string sql = "";
|
||||
if (tt.DataTableName is "" or "")
|
||||
{
|
||||
@ -578,7 +576,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
}
|
||||
internal void SetDataDirName(string tableName, long headerId, string title, string dateDir)
|
||||
{
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
string sql =
|
||||
$"UPDATE [{tableName}] SET AttachDirName = @AttachDirName WHERE HeaderID = @HeaderID AND Title = @Title;";
|
||||
_ = conn.Execute(sql, param: new { HeaderID = headerId, Title = title, AttachDirName = dateDir });
|
||||
@ -586,7 +584,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
|
||||
internal void PurgeExistingData(int toolTypeId, string title)
|
||||
{
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
_ = conn.Execute("PurgeExistingData", param: new { ToolTypeID = toolTypeId, Title = title }, commandType: CommandType.StoredProcedure);
|
||||
}
|
||||
|
||||
@ -600,7 +598,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
throw new Exception("OpenInsight export not available for " + tt.ToolTypeName);
|
||||
|
||||
DataSet ds = new();
|
||||
using (DbConnection conn = GetDbConnection())
|
||||
using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
|
||||
{
|
||||
DbProviderFactory factory = GetDbProviderFactory(conn);
|
||||
|
||||
@ -629,7 +627,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
|
||||
ToolType tt;
|
||||
StringBuilder stringBuilder = new();
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
_ = stringBuilder.Append(" SELECT * FROM ( ");
|
||||
for (int i = 0; i < toolTypes.Length; i++)
|
||||
{
|
||||
@ -661,7 +659,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
if (tt is null)
|
||||
throw new Exception("Invalid tool type ID");
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
string sql = $"SELECT ID, InsertDate, AttachmentID, Title, [Date], {tt.ID} AS ToolTypeID, '{tt.ToolTypeName}' AS ToolTypeName, Reactor, RDS, PSN FROM {tt.HeaderTableName} ORDER BY [Date] DESC ";
|
||||
|
||||
if (pageNo.HasValue && pageSize.HasValue)
|
||||
@ -694,7 +692,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
|
||||
List<KeyValuePair<string, string>> r = new();
|
||||
|
||||
using (DbConnection conn = GetDbConnection())
|
||||
using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
|
||||
{
|
||||
DbProviderFactory factory = GetDbProviderFactory(conn);
|
||||
|
||||
@ -741,7 +739,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
}
|
||||
else
|
||||
{
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
r = conn.Query<AwaitingDisposition>("GetAwaitingDispo", commandType: CommandType.StoredProcedure);
|
||||
}
|
||||
return r;
|
||||
@ -753,7 +751,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
if (tt is null)
|
||||
throw new Exception("Invalid tool type ID");
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
if (clearDate)
|
||||
{
|
||||
// if it's already past the 6 hour window, then it won't show in queue anyway, so need to return value so we can show that
|
||||
@ -775,7 +773,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
if (tt is null)
|
||||
throw new Exception("Invalid tool type ID");
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
string sql =
|
||||
$"SELECT TOP 1 AttachmentID FROM [{tt.HeaderTableName}] WHERE Title = @Title ORDER BY InsertDate DESC";
|
||||
return conn.ExecuteScalar<Guid>(sql, param: new { Title = title });
|
||||
@ -787,7 +785,7 @@ public class MetrologyRepository : IMetrologyRepository
|
||||
if (tt is null)
|
||||
throw new Exception("Invalid tool type ID");
|
||||
|
||||
using DbConnection conn = GetDbConnection();
|
||||
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
|
||||
string sql =
|
||||
$"SELECT TOP 1 AttachmentID FROM [{tt.DataTableName}] WHERE Title = @Title ORDER BY InsertDate DESC";
|
||||
return conn.ExecuteScalar<Guid>(sql, param: new { Title = title });
|
||||
|
Reference in New Issue
Block a user