Sterling database created from Windows Console app won't read inside WP7 app
I have created a Sterling database inside a standard Windows console app, then I have added that database file as a resource inside a WP7 app. I find that the database reading code causing an ArgumentNullException when accessing the LazyValue.Value member.
Here's the database creation code, excluding the model 'Venue'.
public class TestDatabaseInstance : BaseDatabaseInstance
{
public override string Name
{
get
{
return "TestDatabase";
}
}
protected override List<ITableDefinition> RegisterTables()
{
return new List<ITableDefinition>
{
CreateTableDefinition<Venue, int>(x=>x.VenueId)
};
}
}
class Program
{
static void Main(string[] args)
{
//CreateData();
LoadData();
}
private static void CreateData()
{
using (SterlingEngine engine = new SterlingEngine())
{
engine.Activate();
var databaseInstance = engine.SterlingDatabase.RegisterDatabase<TestDatabaseInstance>();
for (int i = 100; i < 1000; i++)
{
var venue = new Venue();
venue.Name = "test";
venue.AddressLine1 = "this is an address";
venue.VenueId = i;
var key = databaseInstance.Save<Venue>(venue);
}
FileStream fs = File.Open("c:\\myvenuedata.dat", FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Write);
using (var binaryWriter = new BinaryWriter(fs))
{
engine.SterlingDatabase.Backup<TestDatabaseInstance>(binaryWriter);
}
databaseInstance = null;
}
}
private static void LoadData()
{
SterlingEngine engine = new SterlingEngine();
var开发者_Python百科 fs = File.Open("c:\\myvenuedata.dat", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
engine.Activate();
var databaseInstance = engine.SterlingDatabase.RegisterDatabase<TestDatabaseInstance>();
engine.SterlingDatabase.Restore<TestDatabaseInstance>(new BinaryReader(fs));
engine.Dispose();
engine = new SterlingEngine();
engine.Activate();
// THIS LINE WORKS FINE IN MY CONSOLE APP
databaseInstance.Query<Venue, int>().ForEach(x => Console.WriteLine(x.LazyValue.Value.Name));
}
}
Then if I put the equivalent code inside the WP7 app:
SterlingEngine engine = new SterlingEngine();
StreamResourceInfo sri = Application.GetResourceStream(new Uri("/SterlingDBReader;component/myvenuedata.dat", UriKind.RelativeOrAbsolute));
var fs = sri.Stream;
engine.Activate();
var databaseInstance = engine.SterlingDatabase.RegisterDatabase<TestDatabaseInstance>();
engine.SterlingDatabase.Restore<TestDatabaseInstance>(new BinaryReader(fs));
engine.Dispose();
engine = new SterlingEngine();
engine.Activate();
// **Errors with ArgumentNullException here because x.LazyValue.Value IS NULL.**
databaseInstance.Query<Venue, int>().ForEach(x => Debug.WriteLine(x.LazyValue.Value.Name));
The only differences are
- that the parent namespace of the reader WP7 app is different to the console app
- It's a WP7 app reading from a console app created data file
- It loads the data file from isolated storage as a resource
Any ideas? thanks Kris
Currently Sterling stores types using the fully qualified assembly type name. That means the referenced classes should be in the exact same project = preferably a shared Silverlight 3 DLL. If you are just linking the files and recompiling it won't work due to this. The goal is to change this in version 2.0 to improve the type checking but that's the case for now.
As far as I know, the type is an important part of the storage mechanism for Sterling, so you'd need to make sure that the namespaces and type names of the type that are stored in the database to match exactly.
I have no idea if the scenarion your suggesting is a supported one, though the restore approach sounds like it should work. I'd recommend asking on CodePlex.
Given the exception you're getting, it sounds like the type names might not match properly, hence the LazyValue.Value being null.
精彩评论