Windows Phone Mango Feature Update

Windows Phone Mango Feature Update

Over at BuildMobile.com I posted about all the awesomeness that is Windows Phone 7.5 (aka the Mango update). There are a couple of features that I either overlooked or were announced after that post went to air:

– Firstly, if I wasn’t clear: The final version of the Windows Phone SDK 7.1 is now available and can be downloaded via the Web Platform Installer (WebPI).

– Not only is the Microsoft Advertising Ad Control included within the SDK, it’s also now available in 11 countries, including Australia.

– There is now a web version of the Marketplace allowing you to purchase and invoke the download of applications directly to your phone.

– Windows Phone 7.5 supports Internet Sharing (ie tethering). Unfortunately this won’t immediately be available on all devices across all carriers but the potential is there – complaining to your telco might affect their decision to roll it out….

– The UserVoice site for Windows Phone has reopened for continual feedback on new product features.

Working with Many-to-Many Relationships in OData via WCF Data Services

Working with Many-to-Many Relationships in OData via WCF Data Services

The WCF Data Service implementation of OData makes for fantastic demo-ware, meaning you’re able to quickly knock up sample applications where you publish simple data base schemas and consume them in a Windows Phone, Silverlight or WPF application. However as soon as you start to do anything moderately complex the model seems to break. In my previous post “Windows Phone LINQ to SQL and the INotifyPropertyChanged and INotifyPropertyChanging Interfaces” I highlighted where the strongly typed client proxy classes fail when you start to Expand a number of entity relationships in a Select statement. In this post we’re going to take a quick look at working with Many-to-Many relationships and the failings specifically around updates.

Let’s work with a simple database schema where we have a table of Movies, and each movie can be assigned to multiple Genres. Of course, many different movies may be assigned to a single Genre, hence we have a many-to-many relationship. In our database schema this is represented using a linking table, MovieGenre, which has two columns representing the MovieId and the GenreId. The primary key is both columns.

In our entity model consumes this joining table, simply exposing the relationship as a collection on both Genre and Movie, as illustrated by the many-to-many association in the following entity model image.

image

For the most part working with this data is simple. We can query the movie data in exactly the same way that we do normally, for example:

var movies = from m in movieEntities.Expand(“Genres”)
                        select m;

The issues start to arise when you want to modify the genres that are associated with a movie. Adding a Genre is easy (newGenre is an existing Genre retrieved from the Genre table):

movie.Genres.Add(newGenre);

This is handled correctly by the client library and the appropriate POST is made to WCF Data Services to add the Genre to the Genres collection on the Movie (and hence to the MovieGenres table). What doesn’t work is removing a Genre. For example the following does NOT work:

movie.Genres.Remove(newGenre);

In fact, when you run this the request that is sent back to WCF Data Service attempts to delete the actual Genre from the database (luckily when I discovered this I hadn’t permitted write access to the table I was working with so this failed).

The work around is to call the AddLink and RemoveLink methods to add the appropriate links between the entities. Unfortunately these methods again require the use of string literals:

AddLink(movie, “Genres”, newGenre);

RemoveLink(movie, “Genres”, newGenre);

We can again use the same trick we used in the previous post to create a helper method that can ensure we have strongly typed code. The following codes actually replaces the existing related entities with a new set by iterating through and either adding or removing the appropriate entities.

public static void UpdateRelatedEntities<TSource, TTarget>(this DataServiceContext entities,
    TSource source,
    Expression<Func<DataServiceCollection<TTarget>>> collectionProperty,
    IEnumerable<TTarget> newRelatedEntities) {
    var memberExpression = collectionProperty.Body as MemberExpression;
    string collectionName = memberExpression.Member.Name;
    var sourceProperty = source.GetType().GetProperty(collectionName).GetValue(source, null) as IEnumerable<TTarget>;
    foreach (var genre in sourceProperty) {
        if (!newRelatedEntities.Contains(genre)) {
            //movie.Genres.Remove(genre);
            entities.DeleteLink(source, collectionName, genre);
        }
    }
    //movie.Genres.Clear();
    foreach (var newGenre in newRelatedEntities){
        if (!sourceProperty.Contains(newGenre)) {
            //movie.Genres.Add(newGenre);
            entities.AddLink(source, collectionName, newGenre);
        }
    }
}

The following demonstrates using this code:

movieEntities.UpdateRelatedEntities(movie, () => movie.Genres, newGenres);

Would love to think that I’ve missed an obvious way to achieve the same thing – if I have, please drop me an email and I’ll update the post. Apologies as comments are currently disabled.

Windows Phone LINQ to SQL and the INotifyPropertyChanged and INotifyPropertyChanging Interfaces

Windows Phone LINQ to SQL and the INotifyPropertyChanged and INotifyPropertyChanging Interfaces

With Windows Phone 7.5 (aka Mango) we finally get access to SQL Server Compact  via LINQ to SQL from within our applications. In my previous post Change Tracking with SQL Server Compact (LINQ to SQL) on Windows PhoneI demonstrated that you can make use of some additional functionality of SSCE that wouldn’t otherwise be accessible via the managed apis. One of the other things I encourage developers to do is to use Visual Studio or SQL Server Management Studio to actually create their database structure, then use the SqlMetal command line tool to generate the necessary class files. The main reason I do this is because there is an awful lot of repetitive code that you should implement for each table and column in your database. Not only is this a waste of your time to write, it’s also very likely you’ll insert an error or two and then waste countless hours trying to debug your code.

Ok, onto the topic of this post. Lets start with a minimal entity called Movie with appropriate attributes for use with LINQ to SQL:

[Table]
public class Movie {
    [Column(IsPrimaryKey = true,
        IsDbGenerated = true,
        DbType = "INT NOT NULL Identity",
        CanBeNull = false,
        AutoSync = AutoSync.OnInsert)]
    public int MovieId { get; set; }

    [Column]
    public string  Name { get; set; }
 
    [Column]
    public int Year { get; set; }
}

Unlike most examples that you may have seen, the Movie class doesn’t implement either INotifyPropertyChanged or INotifyPropertyChanging. You might be thinking that these interfaces are required for LINQ to SQL to work properly. This is a complete fallacy, LINQ to SQL will work fine with this minimal implementation.

Here’s a couple of points about these two interfaces:

INotifyPropertyChanged

– You only need to implement this interface if you data class is going to change and you want those changes to propagate through to the UI.

– This interface is not required for LINQ to SQL to work

– This interface is not required to do read-once data binding

– If you’re going to be reading data from the data base and simply displaying it on the screen then you can, and should, leave this interface off as it just adds unnecessary clutter (KISS!)

INotifyPropertyChanging

– This interface is not required for LINQ to SQL to work

– This interface is not used by data binding

– You should however implement this interface to facilitate better memory management from LINQ to SQL

Here is an extract from the MSDN documentation around this interface.

http://msdn.microsoft.com/en-us/library/hh286406(v=VS.92).aspx#BKMK_MinimizingMemoryUsage

image

Let’s see this in action:

We’ll start with the Movie class without the INotifyPropertyChanging interface. The database is currently populated with a single Movie. We’ll run the following code and use the performance analysis tool in Visual Studio to examine what the impact is on memory.

var ms = dc.Movies.ToArray();

Thread.Sleep(5000);

Console.WriteLine("*******************************************");
Console.WriteLine("                We’re done!!!");
Console.WriteLine("*******************************************");

From the Debug menu load the Windows Phone Performance Analysis

image

Select Memory profiling and click the Launch Application link

image

Note that in the code above we were using Console.WriteLine to indicate when the 5 second sleep has finished. One of the issues with the performance tool is that because the debugger is not attached you can’t see anything in the Visual Studio Output window. However, the emulator does have a console window which you can enable so that you can see the Console.Writeline output.

Follow this link to enable the console window on your computer: Windows Phone 7 Console Window on 64 bit machine

image

Now, lets drill into the performance report. Note that you can see two instances of the Movie class have been loaded into memory. This is consistent with what the MSDN documentation said would happen.

image

Now, let’s implement INotifyPropertyChanging. For example the Name property now looks like this

private string name;
[Column]
public string Name
{
    get { return name; }
    set
    {
        if (name == value) return;
        NotifyPropertyChanging("Name");
        name = value;
    }
}

And, let’s change our code so that in addition to loading the Movie into memory, we’ll change the Name property after five seconds.

var ms = dc.Movies.ToArray();

Thread.Sleep(5000);

ms.First().Name = "Changed name";
Thread.Sleep(5000);

Console.WriteLine("*******************************************");
Console.WriteLine("                We’re done!!!");
Console.WriteLine("*******************************************");

Now when we run the performance analysis we should see that for the first five seconds there is one Movie in memory. Then when we change the Name property a second instance is created to track the original and changed entities. This is hard to see in the performance tool as the Movie entity is tiny. However, thanks to John from Soul Solutions for pointing out this simple but effective trick I added a 10Mb byte array to the Movie class. This makes it much easier to see when each Movie instance is created in the performance analysis.

private byte[] bytes = new byte[1024*1024*10];

The output:

image

In the first time block there is a single Movie instance, as expected. Then when we modify the Name property (at approx 15 time marker) another 10Mb block is allocated to a second Movie instance. Of course, don’t forget to remove the 10Mb byte array when you are finished debugging your memory management!

This illustrates how important it is to implement INotifyPropertyChanging if you have a large number or large entities in your LINQ to SQL database.