0

When writing a C# console App, and using System.Data.SQLite, I am able to perform SQL commands such as:

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

However, when I try using a similar command in Xamarin.Forms, using the sqlite-net-pcl package, I get the followin error: SQLite.SQLiteException: 'no such function: cos'

I have found a similar question on SO (Custom SQLite functions in Xamarin.iOS). However, I didn't fully understand the response. I now have the following questions:

1) Can I make custom SQL functions using sqlite-net-pcl in Xamarin.Forms? If so, could someone please share a simple (but complete) example of how to do this? 2) Is there anyway for me to access the same math functions (pow, cos, sin, etc.) that I can access when writing console Apps in C#? 3) Is there another way to do this? For example, can I read columns from the database into a List, then perform the required math functions, and feed that back into the database? Would this be a terrible idea with a large database?

Thanks in advance,

Dustin

TwoChain
  • 1
  • 5

2 Answers2

0
  1. First is OK.

The SQLite-net PCL by Frank Kreuger is the one that Xamarin University uses in their XAM160 - Working with SQLite and Mobile Data class: https://university.xamarin.com/classes/track/cross-platform-design

  1. Second is Ok.

You can find some documentation on how to get started on the Xamarin developer site: http://developer.xamarin.com/recipes/android/data/databases/sqlite/

  1. Third answer is clear.

More Info:

You can refer to official document in here, Another similar discussion may be helpful for you this.

Junior Jiang
  • 12,430
  • 1
  • 10
  • 30
  • Hi johnheaven, Thank you for your reply. To be clear, I already know how to interact with a database. My question is whether I can use functions such as "cos" and "pow" in an SQLite command (I am able to do this with a normal C# console App, but haven't been able to do it using SQLite-net-PCL). In none of the links you sent was I able to see: 1) How to write a custom function to be used in an SQLite command with SQLite-net-PCL, or 2) How to access "cos" and other math functions directly in the SQLite command. From your response, it seems that you are saying this is possible. Am I correct? – TwoChain Nov 07 '18 at 04:54
0

Correct me if I'm wrong, but what you're trying to do is essentially have two columns where one contains a set of data, and the other contains the result of a simple mathematical operation from the first column. From this you have two columns where one is dependent on the other, which means you are occupying double the necessary memory space. For a 100 entries, that's alright. For 1,000,000? Less so.

I personally thing you are better off not having cosColumn, and you should calculate the cosine when you read the data. For example:

// In your C# code...

public class MyData
{
    public double Column1 { get; set; } = 0.0;
    public double Cosine => Math.Cos(Column1);
}

In the above, the cosine value is never stored or created in neither C# or SQLite, but it is obtained only when needed. This makes it much more memory-friendly to the SQLite table, and it implements a better SQLite structure.


In the code above, the line:

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

is exactly equivalent to:

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

There's no real difference between the two, and you save a lot of line-space. You can find more information on the => notation from this StackOverflow answer by Alex Booker.

Let's go through an example of implementing this structure. Suppose you have a database with 1 column with the name Column1, and you want to apply a Cosine function to this value and display it. Your code might look like:

// 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();

The object data will store the value of Column1 from the database in Column1, but not Cosine. The value of Cosine is only obtained when you call data.Cosine.

Tom
  • 1,739
  • 15
  • 24
  • Hi Tom, Your interpretation of my question is exactly correct, and I think what you are suggesting makes sense. However, it is not clear to me how I would implement your suggestion. I have an external SQLite database that I have added to my project, and am interacting with. This database has 8 columns, and I have made a matching (same name/column names/data types) C# Class to interact with the database. Are you suggesting that in my C# database class, I can replace the {get;set} with something like: =>Math.Cos(Column1)? – TwoChain Nov 07 '18 at 04:45
  • Essentially, yes. In the example I wrote, `Cosine` isn't a database column name, just a class property, whereas `Column1` is a database column. The value of the `Cosine` property is dependent on the value of `Column1` but is not stored in neither the database, nor in memory. I'll edit my answer to better illustrate this. – Tom Nov 07 '18 at 10:49
  • Hi Tom, Thanks for your very detailed reply. I believe I now see what you are saying. To use this on an entire column of data, are you recommending that I use a for loop to loop through each row in the column (I think in your example you are only pulling out data from one row)? Thanks again. – TwoChain Nov 11 '18 at 01:33
  • It depends on how you are using your data. If you are just displaying your data, you may benefit from using `Binding`s. Otherwise, yes, you may have to you a `for` loop. – Tom Nov 12 '18 at 09:31