0

I'm trying to set up SQLite for unit testing with Fluent NHibernate as shown here but the table names isn't being generated as I expected.

Some tables have schemas with dots inside which seems to break the generation. (Dots works perfectly well with Microsoft SQL Server which I have in my production environment.)

Example:

[Foo.Bar.Schema].[TableName]

Result:

TestFixture failed: System.Data.SQLite.SQLiteException : SQLite error
unknown database Foo

How do I instruct SQLite to translate the dots to underscores or something so I can run my unit tests?

(I've tried adding brackets to the schema names with no success)

Jonas Stensved
  • 14,378
  • 5
  • 51
  • 80

1 Answers1

1

You can use a convention http://wiki.fluentnhibernate.org/Conventions

*UPDATED

public static class PrivatePropertyHelper
    {
        // from http://stackoverflow.com/questions/1565734/is-it-possible-to-set-private-property-via-reflection
        public static T GetPrivatePropertyValue<T>(this object obj, string propName)
        {
            if (obj == null) throw new ArgumentNullException("obj");
            PropertyInfo pi = obj.GetType().GetProperty(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (pi == null) throw new ArgumentOutOfRangeException("propName", string.Format("Property {0} was not found in Type {1}", propName, obj.GetType().FullName));
            return (T)pi.GetValue(obj, null);
        }
    }

public class CustomTableNameConvention : IClassConvention
{
    // Use this to set schema to specific value
    public void Apply(FluentNHibernate.Conventions.Instances.IClassInstance instance)
    {
        instance.Schema("My_NEw_Schema");
        instance.Table(instance.EntityType.Name.CamelToUnderscoreLower());
    }


    // Use this to alter the existing schema value.
    // note that Schema is a private property and you need reflection to get it
    public void Apply(FluentNHibernate.Conventions.Instances.IClassInstance instance)
    {          
        instance.Schema(instance.GetPrivatePropertyValue<string>("Schema").Replace(".", "_"));
        instance.Table(instance.EntityType.Name.CamelToUnderscoreLower());
    }
}

You must use only one of he Apply methods.

*UPDATE 2 I don't know I would recommend this but if you like to experiment this seems to work. Even more reflection :)

    public static void SetSchemaValue(this object obj, string schema)
    {

        var mapping_ref  = obj.GetType().GetField("mapping", BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.GetField | BindingFlags.NonPublic).GetValue(obj);

        var mapping = mapping_ref as ClassMapping;
        if (mapping != null)
        {
            mapping.Schema = schema;
        }
    }


    public void Apply(FluentNHibernate.Conventions.Instances.IClassInstance instance)
    {
        var schema = instance.GetPrivatePropertyValue<string>("Schema");
        if (schema == null)
        {
            instance.Schema("My_New_Schema");
        }
        else
        {
            instance.SetSchemaValue("My_New_Schema");
        }
    }
Yavor Shahpasov
  • 1,453
  • 1
  • 12
  • 19
  • I have the schema name set in the ClassMap. The conventions does not apply if the value is specifically set. I noticed this in the [source here](http://www.symbolsource.org/Caliper/Metadata/Default/Project/Fluent-NHibernate/1.0RTM/Release/All/FluentNHibernate/FluentNHibernate/Conventions/Instances/ClassInstance.cs). – Jonas Stensved Aug 11 '11 at 09:32
  • If you apply instance.Schema("Something") it will definitively override the existing value. See updated example above. – Yavor Shahpasov Aug 11 '11 at 10:13
  • Thank you. I tried a similar approach with instance.Schema((IClassInspector)instance).Schema.Replace('.', '_')) but it seems like instance.Schema() won't set the property if it's already set. I can get the name and replace but it won't override the schema in the mapping. – Jonas Stensved Aug 11 '11 at 15:34
  • If you are feeling adventurous but try the updated code above. :) – Yavor Shahpasov Aug 11 '11 at 18:20
  • Your solution works but I ended up simplified my schemas since it wasn't any real trade-off. Thank you for your time :) – Jonas Stensved Aug 29 '11 at 09:17
  • Changing the schema was the better way for sure – Yavor Shahpasov Aug 29 '11 at 23:55