【问题标题】:Accessing math functions with sqlite-net-pcl and Xamarin.Forms使用 sqlite-net-pcl 和 Xamarin.Forms 访问数学函数
【发布时间】:2019-04-07 20:03:58
【问题描述】:

在编写 C# 控制台应用程序并使用 System.Data.SQLite 时,我能够执行 SQL 命令,例如:

string cosfun = string.Format("UPDATE test SET cosColumn = column1*cos(20));

但是,当我尝试在 Xamarin.Forms 中使用 sqlite-net-pcl 包中的类似命令时,我收到以下错误:SQLite.SQLiteException: 'no such function: cos'

我在 SO (Custom SQLite functions in Xamarin.iOS) 上发现了一个类似的问题。但是,我并没有完全理解这个反应。我现在有以下问题:

1) 我可以在 Xamarin.Forms 中使用 sqlite-net-pcl 制作自定义 SQL 函数吗?如果是这样,有人可以分享一个简单(但完整)的例子来说明如何做到这一点吗? 2) 我是否可以访问在 C# 中编写控制台应用程序时可以访问的相同数学函数(pow、cos、sin 等)? 3)还有其他方法可以做到这一点吗?例如,我可以将数据库中的列读入列表,然后执行所需的数学函数,并将其反馈到数据库中吗?对于大型数据库,这会是一个糟糕的主意吗?

提前致谢,

达斯汀

【问题讨论】:

    标签: sqlite xamarin.forms sqlite-net-pcl


    【解决方案1】:
    1. 第一个没问题。

    Frank Kreuger 的 SQLite-net PCL 是 Xamarin 大学在其 XAM160 中使用的 - 使用 SQLite 和移动数据课程:https://university.xamarin.com/classes/track/cross-platform-design

    1. 第二个没问题。

    您可以在 Xamarin 开发人员网站上找到一些有关如何入门的文档:http://developer.xamarin.com/recipes/android/data/databases/sqlite/

    1. 第三个答案很明确。

    更多信息:

    你可以参考here的官方文档,另一个类似的讨论可能对你有帮助this

    【讨论】:

    • 您好 johnheaven,谢谢您的回复。需要明确的是,我已经知道如何与数据库交互。我的问题是我是否可以在 SQLite 命令中使用诸如“cos”和“pow”之类的函数(我可以使用普通的 C# 控制台应用程序执行此操作,但无法使用 SQLite-net-PCL 执行此操作)。在您发送的所有链接中,我都看不到:1)如何使用 SQLite-net-PCL 编写要在 SQLite 命令中使用的自定义函数,或 2)如何直接访问“cos”和其他数学函数SQLite 命令。从您的回复来看,您似乎在说这是可能的。我说的对吗?
    【解决方案2】:

    如果我错了,请纠正我,但您要做的实际上是有两列,其中一个包含一组数据,另一个包含来自第一列的简单数学运算的结果。从这里你有两列,其中一列依赖于另一列,这意味着你占用了两倍的必要内存空间。对于 100 个条目,没关系。 1,000,000?少这样。

    我个人认为您最好拥有cosColumn,并且您应该在读取数据时计算余弦。例如:

    // In your C# code...
    
    public class MyData
    {
        public double Column1 { get; set; } = 0.0;
        public double Cosine => Math.Cos(Column1);
    }
    

    在上面,余弦值在 C# 或 SQLite 中都不会存储或创建,而是仅在需要时获取。这使得它对 SQLite 表的内存更加友好,并实现了更好的 SQLite 结构。


    在上面的代码中,行:

    public double Cosine => Math.Cos(Column1);
    

    完全等同于:

    public double Cosine
    {
        get 
        { 
            return Math.Cos(Column1); 
        }
    }
    

    两者之间没有真正的区别,而且您节省了大量的行空间。您可以在 Alex Booker 的 this StackOverflow answer 中找到有关 => 表示法的更多信息。

    让我们看一个实现这个结构的例子。假设您有一个包含 1 列的数据库,其名称为 Column1,并且您希望对该值应用余弦函数并显示它。您的代码可能如下所示:

    // Read from database object of type MyData
    MyData data = ReadOneValueFromDatabase<MyData>();
    
    // Display values in a label
    MyValueLabel.Text = "Database value: " + data.Column1.ToString();
    MyCosineLabel.Text = "Cosine value: " + data.Cosine.ToString();
    

    对象data 会将来自数据库的Column1 的值存储在Column1 中,但不会 CosineCosine的值只有在你调用data.Cosine时才会得到。

    【讨论】:

    • 嗨,汤姆,您对我的问题的解释是完全正确的,我认为您的建议是有道理的。但是,我不清楚我将如何实施您的建议。我有一个外部 SQLite 数据库,已添加到我的项目中,并且正在与之交互。这个数据库有 8 列,我做了一个匹配的(同名/列名/数据类型)C# 类来与数据库交互。您是否建议在我的 C# 数据库类中,我可以将 {get;set} 替换为:=>Math.Cos(Column1)?
    • 基本上,是的。在我写的例子中,Cosine 不是数据库列名,只是一个类属性,而Column1 是数据库列。 Cosine 属性的值取决于Column1 的值,但既不存储在数据库中,也不存储在内存中。我将编辑我的答案以更好地说明这一点。
    • 嗨,汤姆,感谢您非常详细的回复。我相信我现在明白你在说什么了。要在整列数据上使用它,您是否建议我使用 for 循环遍历列中的每一行(我认为在您的示例中,您只是从一行中提取数据)?再次感谢。
    • 这取决于您使用数据的方式。如果您只是显示您的数据,您可能会受益于使用Bindings。否则,是的,您可能需要一个 for 循环。
    猜你喜欢
    • 1970-01-01
    • 2018-07-06
    • 2021-09-17
    • 2017-11-05
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 2023-03-19
    • 2014-06-01
    相关资源
    最近更新 更多