Xamarin Forms And Entity Framework Core

Xamarin Forms And Entity Framework Core

Entity Framework Core of course works on Xamarin Forms, but only with the Android and Universal Windows Platform. It does not work well with iOS which is little sad thing for iOS.

For those with only Android or UWP, let’s have a close look on how to implement Entity Framework Core, in Xamarin Forms with SQLite. Using Entity Framework Core is quiet easy in your PCL (Portable Class Library). Location of the .db file is the only platform specific data you need to pass.

A- Project Setup

Convert Portable Class Library, into .NET Standard. Read .NET Standard Library with Xamarin Forms. If by any chance you have not done this earlier you need to focus on updating PCL since native projects do not have to be updated to .NET Core.

Note: Do not add SQLite extension in UWP. It is not needed with EF Core and therefore may cause conflict if added.

Ensure that you install Microsoft.EntityFrameworkCore.Sqlite in every project, the traditional and the PCL. This will also install other required dependencies. You are now ready to start the coding part. Get set go.

B- Native Project Setup

For each platform, you must have the path to the SQLite database which will differ from one platform to another. Pass this value into the PCL and such approach is based on your existing architecture. For simpler understanding, pass this through constructor of the App.cs.

// Android
var dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "exrin.db");

// UWP
var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "exrin.db");

// iOS
var dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "..", "Library", "exrin.db");

For getting started with coding that’s all what you want as of now. Having used entity Framework before, you may have probably created your db context class. Here we have mentioned the db context class which will look something like this:

1. public class DataContext : DbContext
2. {
3.   public DataContext()
4.   {
5.      Database.Migrate();
6.   }
7.  
8.   public DbSet<Random> Randoms { get; set; }
9.  
10.   protected override void OnConfiguring(DbContextOptionsBuilder
11.      optionsBuilder)
12.   {
13.      string connectionStringBuilder = new
14.         SqliteConnectionStringBuilder()
15.      {
16.         DataSource = "random.db"
17.      }
18.      .ToString();
19.  
20.      var connection = new SqliteConnection(connectionStringBuilder);
21.      optionsBuilder.UseSqlite(connection);
22.   }
23. }

Viewing the above code we first have to look at the override we have in place for the ‘OnConfuguring’ method. In override, we have created a connection string using the SqliteConnectionStringBuilder class. You can name the database by passing a string to the ‘DataSource’ property. Here we have named our database ‘random.db.

EntityFramework recognises the property of type DbSet, where T in this case is ‘Random’. This property represents a table in your database.

You can also see the line of code in the constructor for our db context.

If you haven’t created a class to quell the voices of Intellisense it may at this point give you an error saying it can’t find Random.

1. public class Random
2. {
3.   public int Id { get; set; }
4.  
5.   public string Name { get; set; }
6. }

Migrations
Let us go into the coding part in order to add an item to our database at runtime in a moment. Before moving further we need to create our SQLite database file. For this writing, we are here using migrations as it is to use in EF Core. it is very clearly visible when you look at the ‘DataContext’ class above, which includes line:

1. 1Database.Migrate();

Another option is…

1. Database.EnsureCreated();

It completely depends on you to explore the various options, but EnsureCreated pretty much does what it says on the box. It ensures that when you new the context up, the database is created; and if it has not, it will create it. But as we are using Migrate(), therefore we won’t using EnsureCreated() for this application.

Henceforth, we need to create our migration. As you are pretty much sure that you have installed the package ‘EntityFramework.Commands, now open your Package Manager Console and use this command..

1. Add-Migration

It will ask you for your migration name. Apply accordingly. we used ‘Initial-Migration’ here in the application. Now press Enter, and away it will go, therefore creating your migration. And you are done. You need not to update your database through the package manager console as the line of code ‘Database.Migrate()’ will do this for you at runtime. Also, it will ensure that the database has been created, and it will create it if it does not exist.

The Main Program
Here is the final piece of application. The program.cs.
It’s quiet simple. It asks for a random name, creates a random object, and enters this into the database. The code here will look like.

1. class Program
2. {
3.   static void Main(string[] args)
4.   {
5.      Console.WriteLine("Enter a random name");
6.      string randomName = Console.ReadLine();
7.  
8.      Random random = new Random()
9.      {
10.         Name = randomName,
11.      };
12.  
13.      DataContext db = new DataContext();
14.  
15.      db.Randoms.Add(random);
16.      db.SaveChanges();
17.   }
18. }

C- While Working With iOS – a downside

Running the same on iOS will give below mentioned error:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NotImplementedException: Interpreter of ref types
 at Microsoft.Scripting.Interpreter.LightCompiler.CompileMethodCallExpression (System.Linq.Expressions.Expression expr) [0x00089] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.114/src/mono/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs:1283 
 at Microsoft.Scripting.Interpreter.LightCompiler.CompileNoLabelPush (System.Linq.Expressions.Expression expr) [0x001ba] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.114/src/mono/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs:1642 
 at Microsoft.Scripting.Interpreter.LightCompiler.Compile (System.Linq.Expressions.Expression expr) [0x00008] in /Library/Fra
meworks/Xamarin.iOS.framework/Versions/10.4.0.114/src/mono/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs:1729 

etc…

There is of course an update on this iOS issue:
The issue is in the LightCompiler.cs (L1280-L1287) of Mono, where it will throw a NotImplementedException(“Interpreter of ref types”). Rowan miller a renowned name in Entity Framework domain has already talked in GitHub Issue 7158 that it will be fixed in a future version of mono, but currently it will be a pain.

Also check out:
Xamarin – Cross Platform App Development Tool | An Infographic and
Why Should Enterprises Use Xamarin for App Development?

Reference: 15mgm15.ghost.io, xamarinhelp.com, erazerbrecht.wordpress.com, codeguru.com

The following two tabs change content below.
Rachit Agarwal

Rachit Agarwal

Director and Co-Founder at Algoworks Technologies
Rachit is leading the mobility business development function, mobility strategy and consulting practice at Algoworks. He is an expert of all mobile technologies and has experience in managing teams involved in the development of custom iPhone/iPad/Android apps.
Rachit Agarwal

Latest posts by Rachit Agarwal (see all)

Rachit AgarwalXamarin Forms And Entity Framework Core