Over a million developers have joined DZone.

Using Entity Framework to Create Databases on Windows Phone Part 3

· Mobile Zone

Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud, brought to you in partnership with IBM.

In part one and part two, we used Entity Framework to create a model to keep track of ideas for other app, generated a .sdf database file, generated data classes then fixed errors in the class so it will work in Windows Phone. In this part we will add some structure to our app, setup the db on first run and populate some default data into some tables. Then finally we will create a couple of views to display the info in the database.

Based on feedback, I would like to clarify that at this point we are done using Entity framework and are using LINQ to SQL to manage the database that we used EF to design in Part 1.

You can grab the source code here.

Part 3: Consuming Data Classes in Windows Phone Application

Now that we have our generated classes in our project, it is time to use them. We do need to do a bit of setup first. In Part 2, we created a folder called Models. This is part of a design pattern that is recommended for all but the most trivial WP7 applications. We will be utilizing this pattern in our application.

The first thing we will do is to add a folder to the AppTracker.WP project called Views.

Now we are going to create a class to handle population of default data in the database. Add a folder called DefaultData to the AppTracker.WP project. In it, add a class called DefaultData.csIn this class we include functions to:
Check if the db exists and deletes it if need be. I use this to help facilitate the initial creation and  re-creation of the db. Useful if you want to add a reset option.

public bool CreateDatabase(bool deleteExisting = false)
{
    try
    {
        if (_context.DatabaseExists())
        {
            if(deleteExisting)
            {
                _context.DeleteDatabase();
            }
            else
            {
                return false;
            }
        }   
        _context.CreateDatabase();
        return true;
    }
    catch (Exception ex)
    {
        if (System.Diagnostics.Debugger.IsAttached)
        {
            MessageBox.Show(ex.Message);
        }
        return false;
    }
}

Populate 5 tables with default data:
public bool PopulateStatusTable()
{
    try
    {
        var statuses = new List<Status>();

        var status = new Status { Id = 1, Name = "In Progress", Description = "Description Description Description Description Description" };
        statuses.Add(status);

        status = new Status { Id = 2, Name = "Games", Description = "Description Description Description Description Description" };
        statuses.Add(status);

        status = new Status { Id = 3, Name = "Other", Description = "Description Description Description Description Description" };
        statuses.Add(status);

        _context.Status.InsertAllOnSubmit(statuses);
        _context.SubmitChanges();

        return true;
    }
    catch (Exception ex)
    {
        if (System.Diagnostics.Debugger.IsAttached)
        {
            MessageBox.Show(ex.Message);
        }
        return false;
    }
}

public bool PopulatePlatformsTable()
{
    try
    {
        var platforms = new List<Platform>();

        var platform = new Platform { Id = 1, Name = "Windows Phone", Description = "Description Description Description Description Description" };
        platforms.Add(platform);

        platform = new Platform { Id = 2, Name = "Android", Description = "Description Description Description Description Description" };
        platforms.Add(platform);

        platform = new Platform { Id = 3, Name = "iOS", Description = "Description Description Description Description Description" };
        platforms.Add(platform);

        _context.Platforms.InsertAllOnSubmit(platforms);
        _context.SubmitChanges();

        return true;
    }
    catch (Exception ex)
    {
        if (System.Diagnostics.Debugger.IsAttached)
        {
            MessageBox.Show(ex.Message);
        }
        return false;
    }
}

public bool PopulateTagsTable()
{
    try
    {
        var tags = new List<Tag>();

        var category = new Tag { Id = 1, Name = "Tag 1", Description = "Description Description Description Description Description" };
        tags.Add(category);

        category = new Tag { Id = 2, Name = "Tag 2", Description = "Description Description Description Description Description" };
        tags.Add(category);

        category = new Tag { Id = 3, Name = "Tag 3", Description = "Description Description Description Description Description" };
        tags.Add(category);

        _context.Tags.InsertAllOnSubmit(tags);
        _context.SubmitChanges();

        return true;
    }
    catch (Exception ex)
    {
        if (System.Diagnostics.Debugger.IsAttached)
        {
            MessageBox.Show(ex.Message);
        }
        return false;
    }
}
public bool PopulateIdeasTable()
{
    try
    {
        var ideas = new List<Idea>();

        var idea = new Idea { Id = 1, Name = "Idea 1", Description = "Description Description Description Description Description", CategoryId = 1, StatusId = 1, DateAdded = DateTime.Now, DateUpdated = DateTime.Now };
        ideas.Add(idea);

        idea = new Idea { Id = 2, Name = "Idea 2", Description = "Description Description Description Description Description", CategoryId = 1, StatusId = 1, DateAdded = DateTime.Now, DateUpdated = DateTime.Now };
        ideas.Add(idea);

        idea = new Idea { Id = 3, Name = "Idea 3", Description = "Description Description Description Description Description", CategoryId = 1, StatusId = 1, DateAdded = DateTime.Now, DateUpdated = DateTime.Now};
        ideas.Add(idea);

        _context.Ideas.InsertAllOnSubmit(ideas);
        _context.SubmitChanges();

        return true;
    }
    catch (Exception ex)
    {
        if (System.Diagnostics.Debugger.IsAttached)
        {
            MessageBox.Show(ex.Message);
        }
        return false;
    }
}


Now that we have a way to populate the tables, lets make that happen. While there are several places to do this, I prefer in the constructor of the MainViewModel.cs file. This makes sure the db is filled when the app is started.
private const string ConnectionString = @"isostore:/AppTrackerDatabase.sdf";
private AppTrackerDataContext _context = new AppTrackerDataContext(ConnectionString);

public MainViewModel() { try { if (!_context.DatabaseExists()) { // create database if it does not exist var dd = new DefaultData.DefaultData(_context); if (dd.CreateDatabase(true)) { if (Debugger.IsAttached) { MessageBox.Show("Database created."); } } else { if (Debugger.IsAttached) { MessageBox.Show("Error creating database"); } } if (dd.PopulateCategoriesTable() && dd.PopulatePlatformsTable() && dd.PopulateStatusTable() && dd.PopulateTagsTable() && dd.PopulateIdeasTable())) { if (Debugger.IsAttached) { MessageBox.Show("Tables populated"); } } else { if (Debugger.IsAttached) { MessageBox.Show("Error populating tables."); } } } else { if (Debugger.IsAttached) { MessageBox.Show("Database Exists."); } } } catch (Exception ex ) { if (Debugger.IsAttached) { MessageBox.Show(ex.Message); } } }


Now we make sure the Items property in the MainViewModel triggers the PropertyChanged event so the UI updates.
private ObservableCollection _ideas;
public ObservableCollection Ideas
{
    get
    {
        return _ideas;
    }
    set
    {
        if (value != _ideas)
        {
            _ideas = value;
            NotifyPropertyChanged("Ideas");
        }
    }
}

Then we update the LoadData function to pull all Idea records load them into the Items ObservableCollection. This loading triggers the PropertyChanged event and causes the UI to update.
public void LoadData()
{
    var ideas = _context.Ideas.Where(i => i.Id != 0);
    Ideas = new ObservableCollection(ideas.ToList());
    this.IsDataLoaded = true;
}

Next we update the MainPage.xaml file to include the CategoryId and StatusId info. I wont be covering data binding in this post but will in the near future.
<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Ideas}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Margin="0,0,0,17" Width="432" Height="200">
                <TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
                <TextBlock Text="{Binding Description}" TextWrapping="Wrap" Margin="12,-6,12,5" Style="{StaticResource PhoneTextSubtleStyle}"/>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="CategoryId: " TextWrapping="Wrap" Margin="12,-6,12,5" Style="{StaticResource PhoneTextSubtleStyle}" Width="122" />
                    <TextBlock Text="{Binding CategoryId}" TextWrapping="Wrap" Margin="12,-6,12,5" Style="{StaticResource PhoneTextSubtleStyle}" Width="193" />
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="StatusId: " TextWrapping="Wrap" Margin="12,-6,12,5" Style="{StaticResource PhoneTextSubtleStyle}" Width="122" />
                    <TextBlock Text="{Binding StatusId}" TextWrapping="Wrap" Margin="12,-6,12,5" Style="{StaticResource PhoneTextSubtleStyle}"/>
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Now if we run the project, we will see a page with the 3 Ideas displayed.

At this point, we have a starting point to an application with a database created from an entity model. If we need to update the entity model in the future, we can follow the steps in the second part and simply update the DataClasses.cs file. Building the solution will then show you any breaking changes and help hunt down where you need to update.

There is still plenty of work to do to make this a marketplace worthy app but we will over the next few months cover these parts until we have something we will actually submit.

The Mobile Zone is brought to you in partnership with Strongloop and IBM.  Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud.

Topics:

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}