SQLite.NET - System.NotSupportedException:无法编译:参数

Zac*_*een 7 c# xamarin.ios .net-4.5 xamarin sqlite.net

我在Xamarin iOS项目中使用SQLite.NET Async(http://www.nuget.org/packages/SQLite.Net.Async-PCL/),但是我在使用表谓词查询时遇到了问题.

任何时候我使用下面的Get方法,这很简单,我收到一个异常,表达式无法编译,System.NotSupportedException:无法编译:参数.

但是,如果我使用低级查询,与GetQuery方法一样,它可以正常工作.在我的表的定义或阻止sqlite.net编译表达式的方法中,我做错了吗?

public interface IDataModel
{
    [PrimaryKey, AutoIncrement]
    int Id { get; set; }
}

public class BaseDataModel : IDataModel
{
    [PrimaryKey]
    public virtual int Id { get; set; }
}

[Table("Event")]
public class EventDataModel : BaseDataModel
{
    public string Name { get; set; }
    public int OrganizationId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime? EndDate { get; set; }
    public bool Active { get; set; }
}

public class DataService<T> : IDataService<T> where T : IDataModel, new()
{

    public virtual async Task<T> Get(int id)
    {
        var connection = await GetConnection();

        return await connection.Table<T>()
                .Where(item => item.Id == id)
                .FirstOrDefaultAsync();
    }

    public virtual async Task<T> GetQuery(int id)
    {
        var connection = await GetConnection();

        return (await connection.QueryAsync<T>("SELECT * FROM Event WHERE Id = ?", id))
             .FirstOrDefault();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑#1:问题似乎与我的方法是通用的事实有关.如果我将它们更改为特定的模型"connection.Table <EventDataModel> .Where(..."它的工作原理.泛型方法不起作用吗?

编辑#2:我在T上添加了一个"类"约束,以配合现有的'IDataModel,new()'约束,这似乎解决了这个问题......这有意义吗?

Jea*_*nal 11

添加class约束可以解决问题.

当你写:

public virtual async Task<T> Get(int id)
    where T : IDataModel, new()
{
    var connection = await GetConnection();

    return await connection.Table<T>()
            .Where(item => item.Id == id)
            .FirstOrDefaultAsync();
}
Run Code Online (Sandbox Code Playgroud)

你没有看到它,但编译器会在item和之间插入一个强制转换item.Id.

也就是说,编译器实际写的是:

public virtual async Task<T> Get(int id)
    where T : IDataModel, new()
{
    var connection = await GetConnection();

    return await connection.Table<T>()
            .Where(item => ((IDataModel)item).Id == id)
            .FirstOrDefaultAsync();
}
Run Code Online (Sandbox Code Playgroud)

插入该强制转换因为如果T是值类型则必须插入.

很容易想象SQLite.net的查询提供程序没有正确处理插入的转换,因为这样做并不简单.

添加class约束允许编译器避免插入该转换,从而产生一个更简单的表达式,SQLite.net查询提供程序显然可以正确转换.