SQLite .NET, ExecuteScalarAsync<int>, how to know when there was no result?

不羁岁月 提交于 2019-12-23 21:36:26

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!