Question

I'm trying to port my WP apps to Windows 8 while maintaining portable model and viewmodel classes. However, my apps have used SQLCE for Windows Phone 7, and so my original model classes are all decorated up with attributes for mapping to SQLCE tables. Since SQLCE isn't available for WinRT apps, I want to abstract data access so that I can continue using SQLCE on the phone, but use SQLite on Windows 8.

Has anyone come up with a sane, working abstraction layer that doesn't eliminate the ability to use IQueryable? Similarly, anyone have success using XML mapping for SQLCE on Windows Phone as opposed to attribute mapping? It'd be nice if I didn't have to manually convert between my model classes and DAL analogues.

(I have a bit of a rant about this on my blog, which may help provide further background on my problem.)

Was it helpful?

Solution

I've determined that having a per-platform "core" assembly for portable code (viewmodels, helpers, etc.) and a separate assembly per database/backing store (SqlCe, Sqlite, etc.) that the platform-specific core assemblies reference seems to work. This means that my model classes are still defined in the DAL assemblies, but I at least can provide a simple, common interface (defined in each DAL assembly, unfortunately, because of the DAL model classes) that still provides me with IQueryable support.

Thanks to "copy as link" in Visual Studio, setting up the core assemblies and ensuring that the common database service interface is the same for each DAL assembly is pretty easy. With #ifdef I can even reuse a lot of the DAL model class files and conditionally compile attributes, database-specific code, etc. which allows me to use "copy as link" for them too.

public interface IDataService
{
    IQueryable<ModelType1> ModelType1 { get; }
    IQueryable<ModelType2> ModelType2 { get; }

    void AddModelType1(ModelType1 item);
    void RemoveModelType1(ModelType1 item);

    void AddModelType2(ModelType2 item);
    void RemoveModelType2(ModelType2 item);

    void CreateDatabase();
    void ResetDatabase();
}

The resulting map of references is kind of like this:

System.Data.Linq -> App.Data.SqlCe -> App.Core.WP -> App.WP
                        /                /
             (some shared code)  (all shared code)
                      /                /
Sqlite -> App.Data.Sqlite -> App.Core.Win8 -> App.Win8

It's nowhere near as clean as I'd like, but at least it seems to work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top