Description
For a project I'm working on, I'm creating a purge feature that deletes old data from this system's database.
I've found that, while my SQL works correctly when ran from SQL Studio, it does not work when ran from C# code. Based on some StackOverflow research, I believe it's due to my needing to call .ExecuteUpdate()
, instead of .UniqueResult<PurgeResult>()
to actually fire the SQL statement. However, my query is returning a PurgeResult
based on if the DELETE statements throw any errors in SQL, so that developers can be informed if something goes wrong.
C# NHibernate Code:
public class PurgeResult {
public int ResultCode { get; set; }
public string Message { get; set; }
public bool IsSuccessful => ResultCode == 1;
}
public static PurgeResult Purge(DateTime purgeTo)
{
// Verified that my purge SQL runs in SQL studio. It only fails
// to delete anything when ran from my C# code.
var sql = @"BEGIN TRY
TRANSACTION PurgeMySystem
DELETE FROM InsertTableHere
WHERE CreateDate <= :PurgeTo
-- Repeat deletes as necessary, specific delete statements may not be
-- relevant to this technical question.
COMMIT TRANSACTION PurgeMySystem
SELECT 1 AS ResultCode, 'Purge successful!' AS Message
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK
END
SELECT 0 AS ResultCode,
CONCAT('Message: ', ERROR_MESSAGE(), '\r\n\r\n', 'At line: ', ERROR_LINE()) AS Message
END CATCH";
using (var session = DatabaseService.CreateSession())
{
var query = session.CreateSQLQuery(sql)
.SetParameter("PurgeTo", purgeTo)
.SetResultTransformer(Transformers.AliasToBean(typeof(PurgeResult));
// Problem line below! I think for DELETE statements to work,
// I need to run query.ExecuteUpdate(), but that only returns an
// int representing row count affected by the statement.
var result = query.UniqueResult<PurgeResult>();
return result;
}
}
Question:
Given a hybrid script above that both DELETEs records and returns a status of that effort, is there a way I can effectively run a script like this in NHibernate? If so, what's the correct way to do what I'm trying to do?
Alternatively: Is there a way to specify what would effectively be an out
parameter to this query, so I could still .ExecuteUpdate()
, and have my result too? In my normal programming, I try to avoid this, but a bool TryDoSomething(out SomeObject resultObject)
pattern in C# isn't unknown, and this situation could well call for something like that setup.