问题
The SQL statement is retrieving the ID of a row. But there may be no such row. When I executed a particular SQL statement in a GUI tool, it returned "0 rows returned in 0ms from:...".
However, when I executed the same SQL statement with ExecuteScalarAsync<int>
, it returned 0, and no exception or null occurred. How do I know if there was no such row? Theoretically, there can be a row whose ID is 0.
PS: It is SQLite-net which I added using Nuget (https://github.com/praeclarum/sqlite-net). Its version is 1.4.118. The SQL statement was very simple one. I changed the field names, but basically it is something like:
using SQLite;
public Task<int> GetLastID()
{
return RealDatabase.ExecuteScalarAsync<int>
("SELECT max(ID) FROM DATA)");
}
回答1:
Indeed, the provider doesn't have nullable types implemented and there's an open issue about it.
Although can either switch to different provider (please advice if you know lightweight alternative), I use the following hack. In my case I can't simple avoid zero (0) value, it has special meaning in database and I must distinguish it from no data.
public Task<int> GetLastID()
{
var sRes = RealDatabase.ExecuteScalarAsync<string>
("SELECT cast(max(ID) as varchar) FROM DATA)");
return string.IsNullOrEmpty(sRes) ? null : int.Parse(sRes);
}
回答2:
I solved this with an extension method:
using System;
using System.Threading.Tasks;
using SQLite;
namespace MyApp.DB
{
public class Row<T>
{
public T scalar_value { get; set; }
}
public class Maybe<T>
{
public readonly T Value;
public Maybe(T v) { Value = v; }
}
public static class SQLiteExtensions
{
public async static Task<Maybe<T>> QueryScalarAsync<T>(this SQLite.SQLiteAsyncConnection conn, string sql)
{
var res = await conn.QueryAsync<Row<T>>(sql);
if (res.Count == 0)
{
return null;
}
else
{
return new Maybe<T>(res[0].scalar_value);
}
}
}
}
A return value of null
signifies no rows found and any return value itself is wrapped in a Maybe
class so that null values can be distinguished:
var version = await conn_.QueryScalarAsync<int>("SELECT version AS scalar_value FROM schema_version");
if (version == null)
{
Debug.WriteLine("no rows found");
}
else
{
Debug.WriteLine(string.Format("value = {0}", version.Value));
}
The only gotcha is that your query must include a column named scalar_value
.
来源:https://stackoverflow.com/questions/47157572/sqlite-net-executescalarasyncint-how-to-know-when-there-was-no-result