Отображение формул в NHibernate для функций в SQLite или Override Mapping - PullRequest
2 голосов
/ 08 декабря 2010

я нашел следующую статью http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx, чтобы помочь мне протестировать мой модуль NHibernate. Большинство моих тестов работают нормально, но была выдана странная ошибка. Глядя на сгенерированный SQL, я считаю, что следующее беглое отображение вызывает проблемы:

Map(x => x.IsValid).Formula("CASE WHEN dbo.NumPosts(UserID) = 5 THEN 1 ELSE 0 END");

Вы заметите вызов dbo.NumPosts, который является определяемой пользователем функцией в моей базе данных. Я знаю, что есть другие способы, которыми я мог бы сопоставить это свойство, но это просто используется в качестве примера. В основном мне нужно знать, как отобразить это с помощью SQLite.

Edit:

После дальнейших размышлений можно ли переопределить сопоставление для этого поля в моем проекте модульного тестирования? Вот моя текущая конфигурация:

private static ISessionFactory CreateSessionFactory() {
    return Fluently.Configure()
        .Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
        .Mappings(m => m.FluentMappings
            .AddFromAssembly(typeof(Role).Assembly)
            .Conventions.AddFromAssemblyOf<EnumConvention>())
        .ExposeConfiguration(c => _configuration = c)
        .BuildSessionFactory();
}

Я не хочу переопределять все сопоставления, так как это займет некоторое время и станет непригодным для обслуживания.

Буду признателен за помощь. Спасибо

Ответы [ 2 ]

1 голос
/ 27 февраля 2012

Ссылаясь на ответ в вашем комментарии, я смог заставить работать статическое свойство bool.

Тем не менее, мне не нравилось полагаться на глобальную переменную bool, поэтому я решил копать дальше. В NHibernate 3.0 они добавили события в объект конфигурации. В частности, я смог воспользоваться новым событием BeforeBind для объекта конфигурации.

Я немного переписал ваш метод CreateSessionFactory (), чтобы показать, как я это сделал.

ПРИМЕЧАНИЕ. В моей формуле я всегда пишу их как dbo.NumPosts, а обработчик событий удаляет 'dbo.' если мы работаем в диалекте SQLite.

private static ISessionFactory CreateSessionFactory()
{
    return Fluently.Configure()
        .Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
        .Mappings(m => m.FluentMappings
                           .AddFromAssembly(typeof (Role).Assembly)
                           .Conventions.AddFromAssemblyOf<EnumConvention>())
        .ExposeConfiguration(c =>
                                 {
                                     c.BeforeBindMapping += BeforeBindMappingHandler;
                                     _configuration = c;
                                 })
        .BuildConfiguration()
        .BuildSessionFactory();
}

private static void BeforeBindMappingHandler(object sender, BindMappingEventArgs e)
{
    if (!(e.Dialect is SQLiteDialect)) return;

    var properties = e.Mapping.RootClasses
        .SelectMany(r => r.Properties)
        .Where(p => p is HbmProperty)
        .Cast<HbmProperty>()
        .Where(p => p.Formulas.Any());

    foreach (var hbmProperty in properties)
        hbmProperty.formula = hbmProperty.formula.ToLower().Replace("dbo.", "");
}
0 голосов
/ 10 декабря 2010

Проблема решена! Я был в состоянии сказать:

[SQLiteFunction(Name = "NumPosts", Arguments = 1, FuncType = FunctionType.Scalar)]
public class NumPosts : SQLiteFunction {
    public override object Invoke(object[] args) {
        ...
    }
}

Теперь все, что мне нужно было сделать, это добавить параметр, чтобы добавить префикс dbo напротив моих функций. Затем в тестовом проекте он устанавливается пустым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...