Nizar posted a message on the news:microsoft.public.objectspaces group with a question on the ObjectPersistence Toolkit. He got an Exception from System.Data.SqlXml with an error message when trying to persist an object from a class that’s essentially the same as this one:
public class Person
public int id;
public string name;
public DateTime birthday;
The message is “Validation error at 5, 8: Cannot locate a domain structure for ‘Console_persistence.Person’ “.
If you are unfamiliar with the ObjectPersistence Toolkit (download it here) here is what it does. It will generate all three schemas for use in ObjectSpaces for an set of classes and will create the corresponding database for you. This means that you can start with just objects/classes and let the rest be generated for you. For every type a table will be generated, and an autoincrement key is added to your object to guarantee a unique key.
When I looked into the problem I found that the three schema files and the database are created. Not correctly enough, because the namespace of the persistent class is indirectly used (amongst other things) in the names of the tables. It kinda works for a single namespace, but leads to the problem that Nizar was experiencing. For a nested namespace (e.g. MyCompany.MyFramework) you get a ArgumentException from System.Data.SqlXml that “Value does not fall within the expected range.”. Also the name of the relational schema is set to the namespace. This gives you two problems:
- The schema name is used to get to the the database object as in DATABASENAME.SCHEMANAME.TABLENAME. This should correspond to a partially qualified name for a SQL Server object DATABASE.OWNER.OBJECT.
For a RSD file that looks like this:
<rsd:Database Name=”ObjectPersistence” xmlns:rsd=”http://schemas.microsoft.com/data/2002/09/28/rsd“>
the db object would be ObjectPersistence.[MyCompany.MyFramework].[MyCompany.MyFramework.Person]
That doesn’t work well as you might guess, especially as the owner is always dbo when the ObjectPersistence Toolkit creates the table. It would have been better if the schema name is dbo. There must be a reason why the schema name is set to the namespace, but I couldn’t figure it out.
- ObjectSpaces doesn’t handle tables and views with dots in them very well. You can check this by changing the schema name to dbo. The same problems as before occur.
- Remove the namespace(s) from the classes.
- Let the application generate the schema files incorrectly. Then edit the rsd.xml file and change the Schema name to dbo at the second line like so:
<rsd:Schema Name="dbo“><rsd:Database Name=”ObjectPersistence” xmlns:rsd=”http://schemas.microsoft.com/data/2002/09/28/rsd“>
Also, change the tablenames in the rsd.xml file to the simple type names, i.e. remove the namespaces. Then edit the msd file and change the Select
attributes of the map:Variable nodes to include the same tablenames:
<map:Variable Name=”Namespace.Person_Rows” Select=”Person” />
<map:Variable Name="Namespace.Person_Rows" Select="Person“>
- Change the source code of the Toolkit project if you dare and recompile.
You would have to change the following on the RsdClasses.cs file.
WARNING: not tested for all circumstances and use at your own risk.
string schemaName = type.ClassTypeInfo.Namespace == null ? “dbo” :
string schemaName = “dbo”;
RelationalSchemaTable rsdTable =
string tableName = type.Name;
int dotIndex = tableName.LastIndexOf(‘.’);
if (dotIndex >= 0)
tableName = tableName.Substring(dotIndex + 1);
RelationalSchemaTable rsdTable =
That got it all working for me.