c# - SQLite.NET - System.NotSupportedException : Cannot compile: Parameter

标签 c# xamarin.ios xamarin .net-4.5 sqlite.net

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

每当我使用下面非常简单的 Get 方法时,我都会收到无法编译表达式的异常,System.NotSupportedException: Cannot compile: Parameter。

但是,如果我使用低级查询,如使用 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();
    }
}

编辑 #1: 这个问题似乎与我的方法是通用的这一事实有关。如果我将它们更改为特定于模型“connection.Table.Where(...”,它会起作用。通用方法会不起作用吗?

编辑#2: 我在 T 上添加了一个“类”约束以与现有的“IDataModel,new()”约束一起使用,这似乎解决了问题...这有意义吗?

最佳答案

添加 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();
}

你看不到它,但编译器会在 itemitem.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();
}

插入该强制转换是因为如果 T 是值类型,则有必要插入该转换。

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

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

关于c# - SQLite.NET - System.NotSupportedException : Cannot compile: Parameter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21961350/

相关文章:

c# - VS 2019 Release模式下优化代码损坏?

c# - Monotouch UITextField 只有数字

ios - 如何仅刷新/重绘 uicollectionview 中的补充 View ?

xamarin - 按下电源按钮后振动器不振动?

android - 添加 mono.android 引用 Xamarin.Forms

c# - Xamarin Forms ToolbarItem 动画效果不佳

c# - CefSharp 与 WPF MVVM

c# - 在没有解决方案文件的情况下使用巡航控制

c# - 当控件变得可见时以编程方式设置焦点

c# - xamarin应用程序SIGSEGV错误