Caution

This documentation is for EF7 onwards. For EF6.x and earlier release see http://msdn.com/data/ef.

Note

This article uses EF 7.0.0-rc1 which is the latest pre-release available on NuGet.org. You can find nightly builds of the EF7 code base hosted on https://www.myget.org/F/aspnetvnext/ but we do not maintain up-to-date documentation for nightly builds.

Getting Started on Universal Windows Platform

In this walkthrough, you will build a Universal Windows Platform (UWP) application that performs basic data access against a local SQLite database using Entity Framework.

Caution

Deploying a UWP application to the app store requires your application to be compiled with .NET Native. When using Entity Framework there are some query APIs you should avoid to ensure your application is compatible with .NET Native.

You can query using simple LINQ operators that do not change the type of results returned by the query
  • Where
  • OrderBy
  • Distinct
  • Skip/Take
  • ToList/ToArray
  • etc.
You cannot use operators that would change the type of results returned by the query. We are working to support these operators and you can track our progress on GitHub.
  • Select (you can select a single property, but not an anonymous type)
  • GroupBy
  • Include/ThenInclude
  • Join
  • etc.
In this article:

Tip

You can view this article’s sample on GitHub.

Prerequisites

The following items are required to complete this walkthrough:

Create a new project

  • Open Visual Studio 2015
  • File ‣ New ‣ Project...
  • From the left menu select Templates ‣ Visual C# ‣ Windows ‣ Universal
  • Select the Blank App (Universal Windows) project template
  • Give the project a name and click OK

Caution

To work around an issue with EF7 and .NET Native, you need to add a runtime directive to your application. This issue will be fixed for future releases.

  • Open Properties/Default.rd.xml
  • Add the highlighted line shown below
    <!-- Add your application specific runtime directives here. -->
    <Type Name="System.Collections.ArrayList" Dynamic="Required All" />

Install Entity Framework

To use EF7 you install the package for the database provider(s) you want to target. This walkthrough uses SQLite. For a list of available providers see Database Providers.

  • Tools ‣ NuGet Package Manager ‣ Package Manager Console
  • Run Install-Package EntityFramework.SQLite –Pre

Later in this walkthrough we will also be using some Entity Framework commands to maintain the database. So we will install the commands package as well.

  • Run Install-Package EntityFramework.Commands –Pre

Create your model

Now it’s time to define a context and entity classes that make up your model.

  • Project ‣ Add Class...
  • Enter Model.cs as the name and click OK
  • Replace the contents of the file with the following code

Caution

The try/catch code to set databaseFilePath is a temporary workaround to enable migrations to be added at design time. When the application runs, databaseFilePath will always be under ApplicationData.Current.LocalFolder.Path. However, that API can not be called when migrations creates the context at design time in Visual Studio. The database is never accessed when adding migrations, so we just return a relative file path that will never be used.

Note

Notice the OnConfiguring method (new in EF7) that is used to specify the provider to use and, optionally, other configuration too.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using Microsoft.Data.Entity;
using System.Collections.Generic;

namespace EFGetStarted.UWP
{
    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite($"Filename=Blogging.db");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Make Blog.Url required
            modelBuilder.Entity<Blog>()
                .Property(b => b.Url)
                .IsRequired();
        }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

        public List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
}

Tip

In a real application you would typically put each class from your model in a separate file. For the sake of simplicity, we are putting all the classes in one file for this tutorial.

Create your database

Now that you have a model, you can use migrations to create a database for you.

  • Build -> Build Solution
  • Tools –> NuGet Package Manager –> Package Manager Console
  • Run Add-Migration MyFirstMigration to scaffold a migration to create the initial set of tables for your model.

Caution

Notice that you need to manually build the solution before running the Add-Migration command. The command does invoke the build operation on the project, but we are currently investigating why this does not result in the correct assemblies being outputted.

Since we want the database to be created on the device that the app runs on, we will add some code to apply any pending migrations to the local database on application startup. The first time that the app runs, this will take care of creating the local database for us.

  • Right-click on App.xaml in Solution Explorer and select View Code
  • Add the highlighted using to the start of the file
1
2
3
4
5
6
using System;
using Microsoft.Data.Entity;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
  • Add the highlighted code to apply any pending migrations
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
        public App()
        {
            Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(
                Microsoft.ApplicationInsights.WindowsCollectors.Metadata |
                Microsoft.ApplicationInsights.WindowsCollectors.Session);
            this.InitializeComponent();
            this.Suspending += OnSuspending;

            using (var db = new BloggingContext())
            {
                db.Database.Migrate();
            }
        }

Tip

If you make future changes to your model, you can use the Add-Migration command to scaffold a new migration to apply the corresponding changes to the database. Any pending migrations will be applied to the local database on each device when the application starts.

EF uses a __EFMigrationsHistory table in the database to keep track of which migrations have already been applied to the database.

Use your model

You can now use your model to perform data access.

  • Open MainPage.xaml
  • Add the page load handler and UI content highlighted below
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<Page
    x:Class="EFGetStarted.UWP.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:EFGetStarted.UWP"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Loaded="Page_Loaded">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel>
            <TextBox Name="NewBlogUrl"></TextBox>
            <Button Click="Add_Click">Add</Button>
            <ListView Name="Blogs">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Url}" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackPanel>
    </Grid>
</Page>

Now we’ll add code to wire up the UI with the database

  • Right-click MainPage.xaml in Solution Explorer and select View Code
  • Add the highlighted code from the following listing
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            using (var db = new BloggingContext())
            {
                Blogs.ItemsSource = db.Blogs.ToList();
            }
        }

        private void Add_Click(object sender, RoutedEventArgs e)
        {
            using (var db = new BloggingContext())
            {
                var blog = new Blog { Url = NewBlogUrl.Text };
                db.Blogs.Add(blog);
                db.SaveChanges();

                Blogs.ItemsSource = db.Blogs.ToList();
            }
        }
    }

You can now run the application to see it in action.

  • Debug ‣ Start Without Debugging
  • The application will build and launch
  • Enter a URL and click the Add button
../_images/create1.png ../_images/list.png