Working with data is an integral part of any application. In .NET development, the Entity Framework is often the preferred data management choice for many developers. The Entity Framework is an object-relational mapper using the .Net platform to work with relational data that can simplify data access coding.

Recently, we released an update to ComponentOne Studio for Xamarin with a new library enabling integration between our CollectionView and EntityFramework Core. This allows an easy use of the Entity Framework Core with Xamarin and ComponentOne controls.

In this article, we’ll use FlexGrid (the ComponentOne Studio for Xamarin data grid) with the Entity Framework Core and an SQLite database.

Entity Framework Core

Entity Framework Core (EF Core) is a lightweight, extensible, cross-platform version of the Entity Framework. It’s slimmed down from the full Entity Framework and .NET Standard compatible. If you’ve previously used Entity Framework on another platform, EF Core should be familiar. The ability to use the library with Xamarin.Forms is a relatively new development, and, while there are a couple of caveats that we’ll cover in the end of this article, it can fill in a data access gap for many developers.

How to use the Entity Framework Core with Xamarin

The first step is to create a new project that uses a .NET Standard library. The newest versions of Visual Studio 2017 and Xamarin have project templates built with .NET Standard in mind, so this has become much smoother than in the past.

You will need to create a new Mobile App using Xamarin’s Cross-Platform template (or our C1 .NET Standard Template), and make sure you’ve selected .NET Standard.

Built-in Xamarin Cross-Platform Template

The C1 Xamarin Cross-Platform Template

Once the solution is created, we'll add the Microsoft.EntityFrameworkCore.Sqlite, C1.CollectionView.EntityFramework, and C1.Xamarin.Grid libraries.

These libraries enable the project to communicate with SQLite (via EF Core), integrate it with the C1.CollectionView, and use it with the FlexGrid control (the ComponentOne data grid).

Adding NuGet packages to Solution

Creating Model and DBContext

We’ll create both the underlying Model and DBContext to define the database schema. This should be familiar if you’ve used Entity Framework on a different platform.

For this example, we’ll mirror the model used for the SQLiteDataBase sample.

First, we’ll create the Model:

    public class Person
    {
        public Person() { }

        public int ID { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public override string ToString()
        {
            return string.Format("[Person: ID={0}, FirstName={1}, LastName={2}]", ID, FirstName, LastName);
        }
    }

Then we’ll create the DBContext that supports it:

public class PeopleContext : DbContext
    {
        public DbSet<Person> Person { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            var dbPath = "SQLiteDataBase.db3";
            switch (Device.RuntimePlatform)
            {
                case Device.iOS:
                case Device.Android:
                    dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), dbPath);
                    break;
            }
            optionsBuilder.UseSqlite($"Data Source={dbPath}");
        }
    }

The OnConfiguring method has some logic in it that ensures that the database is created in the correct path on iOS and Android.

Using EF Core in a Xamarin.Forms page

At this point, using EF Core in your Xamarin.Forms project is straightforward. We'll need to create a new DBContext, ensure the database is created, and pass the database to the EntityFrameworkCollectionView constructor while specifying the object type you used in your model.

You can call the below Load() method in the C# code-behind of your Xamarin.Forms page.

        private async void Load()
        {
            try
            {
                var db = new PeopleContext();              
                await db.Database.EnsureCreatedAsync();

                grid.ItemsSource = new EntityFrameworkCollectionView<Person>(db);
            }
            catch (SqliteException) { throw; }
        }

In this case, the grid object is the FlexGrid data grid control that is defined in Xaml:

       <c1:FlexGrid x:Name="grid" BorderWidth="0" NewRowPosition="Top"/>

FlexGrid provides out-of-the-box support for editing, sorting, adding, and deleting data in your database, and if you want to extend that with further functionality (like a full-text filter) it’s an easy process.

Simply use this modified Xaml:

<Entry x:Name="filter" Placeholder="Enter text to filter FlexGrid"/>
        <c1:FlexGrid x:Name="grid" BorderWidth="0" NewRowPosition="Top" Grid.Row="1">
            <c1:FlexGrid.Behaviors>
                <c1:FullTextFilterBehavior FilterEntry="{x:Reference Name=filter}" HighlightColor="#B00F50" Mode="WhileTyping" MatchNumbers="False" TreatSpacesAsAndOperator="True" />
            </c1:FlexGrid.Behaviors>
        </c1:FlexGrid>
        <Label x:Name="message" Grid.Row="1" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>

When complete, the result will look like this: FlexGrid

Finally, before you run it, make sure that the iOS and Android of your platform projects have the necessary initializations and permissions. You’ll need to set the provider for both platforms:

Android MainActivity.cs:

protected override void OnCreate(Bundle bundle)
        {
            SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_e_sqlite3());
       …

iOS AppDelegate.cs:

        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlite3());
      …

You’ll also need to add permissions to the Android project to access local storage:

Android AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Note: You'll need to disable the Xamarin linking in the iOS project before trying to run the sample on an iOS device.

iOS Caveats

EF Core has limitations to their support in Xamarin and there are some unique challenges on Xamarin.iOS since it requires .NET to work with AOT compilation (whereas the .NET CLR usually compiles JIT).

Xamarin provides more information about these limitations on their site. There are some practical implications where you may find some aspects of EF Core will not work as expected when running on iOS. You may need to test on iOS and adjust your model and logic to work around any issues that arise. It’s worth it to continue checking the active issues in GitHub. Many issues have a workaround or are actively in the process of being fixed.

Also, in our testing, we’d recommend using the “Don’t Link” option when compiling on iOS since the Xamarin linker will remove some EF Core features when deployed to a device. You can configure this by right-clicking on your Xamarin.iOS project and choosing the properties:

FlexGrid

Integrating data with our other UI controls

It’s easy to get EF Core setup to work with the new C1.CollectionView.EntityFramework library. Since the CollectionView is the foundational data management component used throughout the ComponentOne Studio for Xamarin controls, it’s simple to integrate the data with our other UI controls (including charts, calendars, and input controls). We’re excited to be able to support EF Core and the new possibilities it enables.

The full SQLiteDatabase sample is available on GitHub.