Skip to content

Commit

Permalink
📝 Getting Started on UWP
Browse files Browse the repository at this point in the history
First cut at getting started on UWP
  • Loading branch information
rowanmiller committed Jul 29, 2015
1 parent 522124a commit c5da04b
Show file tree
Hide file tree
Showing 26 changed files with 870 additions and 8 deletions.
152 changes: 144 additions & 8 deletions docs/getting-started/uwp.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,149 @@
.. include:: /stub-topic.txt
Getting Started on Universal Windows Platform
=============================================

|stub-icon| 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.

.. include:: /stub-notice.txt
.. caution::
**Beta 6 can be used on UWP but there are a number of known issues that you need to workaround. Look out for caution boxes (such as this one) that provide details of required workarounds.**

.. _issue: https://github.com/aspnet/EntityFramework.Docs/issues/2
We'll be working to address these issues in upcoming releases. In fact, some of them are already fixed in our working code base.

.. danger::
**At this stage there are no publicly available builds of EF7 that can be used with a UWP application.**
In this article:
- `Prerequisites`_
- `Create a new project`_
- `Install Entity Framework`_
- `Create your model`_
- `Create your database`_
- `Use your model`_

The current beta release (Beta 5) does not support UWP. Nightly builds contain work to enable UWP but require updated UWP tooling that is not yet publically available. **We are aiming to enable UWP scenarios with Beta 6 of EF7.**
`View this article's samples on GitHub <https://github.com/aspnet/EntityFramework.Docs/tree/master/docs/getting-started/uwp/sample>`_.

.. note::
This walkthrough uses EF 7.0.0-beta6 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/api/v2/ but the code base is rapidly changing and we do not maintain up-to-date documentation for getting started.

Prerequisites
-------------

The following items are required to complete this walkthrough:
- Windows 10 RTM
- Visual Studio 2015 RTM with Window 10 Developer Tools

.. tip::
If you already have Visual Studio 2015 RTM installed without the Windows 10 Developer Tools, you can add these tools to your existing Visual Studio installation. You can `run the installer <http://go.microsoft.com/fwlink/?LinkID=619615>`_, or open **Programs and Features** from **Control Panel**, select **Visual Studio** and click **Change**. Then in setup, click **Modify** and select the **Tools for Universal Windows Apps**.


Create a new project
--------------------

* Open Visual Studio 2015
* :menuselection:`File --> New --> Project...`
* From the left menu select :menuselection:`Templates --> Visual C# --> Windows --> Universal`
* Select the **Blank App (Universal Windows)** project template
* Give the project a name and click **OK**

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 :doc:`/providers/index`.

* :menuselection:`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``
* Run ``Install-Package Microsoft.CodeAnalysis.CSharp``

.. caution::
Needing to install the **Microsoft.CodeAnalysis.CSharp** package is a workaround for an issue in Beta 6. This will not be required in later releases.

Create your model
-----------------

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

* :menuselection:`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.

.. literalinclude:: uwp/sample/EFGetStarted.UWP/Model.cs
:language: c#
:linenos:

Create your database
--------------------

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

* :menuselection:`Build -> Build Solution`
* :menuselection:`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.

.. caution::
Due to a bug in the migration scaffolder in Beta6 you will need to manually edit the generated migration.

Remove (or comment out) the two calls to ``.Annotation("Sqlite:Autoincrement", true)`` as highlighted in the following code listing

.. literalinclude:: uwp/sample/EFGetStarted.UWP/Migrations/20150729201928_MyFirstMigration.cs
:language: c#
:linenos:
:lines: 10-31
:emphasize-lines: 7-8,19-20

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 lines of code from the following listing

.. literalinclude:: uwp/sample/EFGetStarted.UWP/App.xaml.cs
:language: c#
:linenos:
:lines: 1-25
:emphasize-lines: 2,21-24

.. 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.

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

.. literalinclude:: uwp/sample/EFGetStarted.UWP/MainPage.xaml
:language: c#
:linenos:
:emphasize-lines: 9,12-22

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

.. literalinclude:: uwp/sample/EFGetStarted.UWP/MainPage.xaml.cs
:language: c#
:linenos:
:lines: 23-49
:emphasize-lines: 8-26

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

* :menuselection:`Debug --> Start Without Debugging`
* The application will build and launch
* Enter a URL and click the **Add** button

.. image:: uwp/_static/create.png

.. image:: uwp/_static/list.png
Binary file added docs/getting-started/uwp/_static/create.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/getting-started/uwp/_static/list.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions docs/getting-started/uwp/sample/EFGetStarted.UWP.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EFGetStarted.UWP", "EFGetStarted.UWP\EFGetStarted.UWP.csproj", "{AB09F21A-1935-4AEE-B3CF-A987416EE495}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Debug|ARM.ActiveCfg = Debug|ARM
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Debug|ARM.Build.0 = Debug|ARM
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Debug|ARM.Deploy.0 = Debug|ARM
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Debug|x64.ActiveCfg = Debug|x64
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Debug|x64.Build.0 = Debug|x64
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Debug|x64.Deploy.0 = Debug|x64
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Debug|x86.ActiveCfg = Debug|x86
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Debug|x86.Build.0 = Debug|x86
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Debug|x86.Deploy.0 = Debug|x86
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Release|ARM.ActiveCfg = Release|ARM
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Release|ARM.Build.0 = Release|ARM
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Release|ARM.Deploy.0 = Release|ARM
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Release|x64.ActiveCfg = Release|x64
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Release|x64.Build.0 = Release|x64
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Release|x64.Deploy.0 = Release|x64
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Release|x86.ActiveCfg = Release|x86
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Release|x86.Build.0 = Release|x86
{AB09F21A-1935-4AEE-B3CF-A987416EE495}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
8 changes: 8 additions & 0 deletions docs/getting-started/uwp/sample/EFGetStarted.UWP/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Application
x:Class="EFGetStarted.UWP.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:EFGetStarted.UWP"
RequestedTheme="Light">

</Application>
97 changes: 97 additions & 0 deletions docs/getting-started/uwp/sample/EFGetStarted.UWP/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using System;
using Microsoft.Data.Entity;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace EFGetStarted.UWP
{
sealed partial class App : Application
{
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.ApplyMigrations();
}
}

/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{

#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
this.DebugSettings.EnableFrameRateCounter = true;
}
#endif

Frame rootFrame = Window.Current.Content as Frame;

// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();

rootFrame.NavigationFailed += OnNavigationFailed;

if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}

// Place the frame in the current Window
Window.Current.Content = rootFrame;
}

if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
}

/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}

/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
deferral.Complete();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsights xmlns = "http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
</ApplicationInsights>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c5da04b

Please sign in to comment.