SQLite.NET - System.NotSupportedException:无法编译:参数 [英] SQLite.NET - System.NotSupportedException: Cannot compile: Parameter

查看:27
本文介绍了SQLite.NET - System.NotSupportedException:无法编译:参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using SQLite.NET Async (http://www.nuget.org/packages/SQLite.Net.Async-PCL/) in a Xamarin iOS project, but I am having a problem using the table predicate queries.

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

Anytime I use the Get method below, which is very simple, I receive an exception that the expression could not be compiled, System.NotSupportedException: Cannot compile: Parameter.

但是,如果我使用低级查询,就像使用 GetQuery 方法一样,它可以正常工作.我的表定义或阻止 sqlite.net 编译表达式的方法有什么问题吗?

However, if I use a low level query, as with the GetQuery method, it works fine. Is there something I am doing wrong in the definition of my table or in the method that is preventing sqlite.net from compiling the expression?

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<EventDataModel>.Where(..."它可以工作.通用方法会不起作用吗?

Edit #1: The problem seems to be related to the fact that my methods are generic. If I change them to specific for the model "connection.Table<EventDataModel>.Where(..." it works. Will generic methods not work?

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

Edit #2: I added a 'class' constraint onto T to go along with the existing 'IDataModel, new()' constraints, and that seems to have fixed the issue...Does that make sense?

推荐答案

添加 class 约束可以解决问题确实有意义.

It does make sense that adding a class constraint would solve the issue.

当你写作时:

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 之间插入一个强制转换.

You do not see it, but the compiler will insert a cast between item and item.Id.

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

That is, what the compiler actually writes is:

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 是值类型,则它是必需的.

That cast is inserted because it would be necessary if T is a value type.

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

It is easy to imagine that the query provider for SQLite.net does not handle that inserted cast correctly, as doing so is not trivial.

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

Adding the class constraint allows the compiler to avoid inserting that cast, resulting in a simpler expression that the SQLite.net query provider apparently can translate correctly.

这篇关于SQLite.NET - System.NotSupportedException:无法编译:参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆