Thanks, yeah I’ve called SPs from ormlite lots on our old servicestack service.
We’re porting to netcore and I’m doing a code cleanup and refactor as we go. I was trying to move away from the MultiQuery approach we were using before so there’s less SQL ‘magic’ and the c# program flow reads better.
Do you tend to just write all your sql access in c# in the services and avoid stored procedures?
one scenario stored procs (and views) come in handy is when you have to deal with a less than ideal legacy data model… the procs & views create the abstraction of the more preferred model and map it back into actual tables… allows you to avoid proliferating undesirable structure into C# logic and creates opportunities for a cleaner future while you go along without being disruptive to legacy dependencies on the existing schema… it’s the basis of a transitional change management strategy.
Not sure if this is still an issue, but here is an example:
public async Task<(int, List<Guid>)> Search(string searchString,
IEnumerable<KeyValuePair<string, string>> filterParams, int skip, int take, CancellationToken ct = default)
{
var dataTableTmp = new DataTable();
dataTableTmp.Columns.Add("searchKey", typeof(string));
dataTableTmp.Columns.Add("searchValue", typeof(string));
if (filterParams != null)
{
foreach (var item in filterParams)
{
dataTableTmp.Rows.Add(item.Key, item.Value);
}
}
var result = new List<Guid>();
var totalCount = 0;
using (var db = await dbFactory.OpenAsync(ct).ConfigureAwait(false))
{
ct.ThrowIfCancellationRequested();
result.AddRange(db.Exec(dbCmd =>
{
dbCmd.CommandType = CommandType.StoredProcedure;
dbCmd.Parameters.Add(new SqlParameter("@filterParams", dataTableTmp));
dbCmd.Parameters.Add(new SqlParameter("@searchString", searchString ?? ""));
dbCmd.Parameters.Add(new SqlParameter("@skip", skip));
dbCmd.Parameters.Add(new SqlParameter("@take", take));
var outputParam = new SqlParameter("@totalCount", DbType.Int32);
outputParam.Direction = ParameterDirection.Output;
dbCmd.Parameters.Add(outputParam);
dbCmd.CommandText = "spSearch";
var result = dbCmd.ConvertToList<Guid>();
totalCount = (int)outputParam.Value;
return result;
}));
}
return (totalCount, result);
}
This will return a list of GUIDs (which in out case is a list of profile IDs we are looking for)
Keep in mind that you need to create the custom data type in SQL as well and it needs to match the signature of the DataTable.
Also, this particular SP gives the total number of matched items in the @totalCount ouput param. Might be handy for skip/take functionality.