Sqlite NHibernate SchemaUpdate从不更新我的模式

Sqlite NHibernate SchemaUpdate从不更新我的模式,sqlite,nhibernate,fluent-nhibernate,Sqlite,Nhibernate,Fluent Nhibernate,我正在从事一个利用NHibernate和FluentNHibernate的项目(我是这两种技术的新手),我需要更新SQLite生产数据库的模式。 我读过许多帖子,其中明确指出,SchemaUpdate可以实现这一点(前提是更新不会造成破坏,比如添加新的可空列,而不是删除它们),但我从未实现过这一点 我需要用SQLite来做,但我也用Postgres9.3和SQLServer2008R2测试了它,但总是不成功 为了简单起见,我创建了以下简单程序,以便在第一次启动时创建一个简单的表并填充它。在第二次

我正在从事一个利用NHibernate和FluentNHibernate的项目(我是这两种技术的新手),我需要更新SQLite生产数据库的模式。 我读过许多帖子,其中明确指出,SchemaUpdate可以实现这一点(前提是更新不会造成破坏,比如添加新的可空列,而不是删除它们),但我从未实现过这一点

我需要用SQLite来做,但我也用Postgres9.3和SQLServer2008R2测试了它,但总是不成功

为了简单起见,我创建了以下简单程序,以便在第一次启动时创建一个简单的表并填充它。在第二次启动之前,我用“StringValue2”取消了这三行的注释。因此,我希望用新列“StringValue2”扩展我的简单表,但该表从未得到更新

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SQLite;
using NHibernate;
using FluentNHibernate.Cfg.Db;
using System.Diagnostics;
using FluentNHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using FluentNHibernate.Mapping;

namespace SchemaUpdatePOC
{
    class Program
    {
        static ISessionFactory sessionFactory = null;

        static void Main(string[] args)
        {
            try
            {
                sessionFactory = CreateSessionFactory();
                AddRow("aaa1", 10, DateTime.Now, true, "123");
                AddRow("bbb1", 20, DateTime.Now.AddHours(1), false, "456");
                AddRow("ccc1", 30, DateTime.Now, true, "789");
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        private static ISessionFactory CreateSessionFactory()
        {
            try
            {
                // SQLite
                string connString = "Data Source=TestDB.s3db;Version=3;";
                IPersistenceConfigurer configurer = SQLiteConfiguration.Standard.ConnectionString(connString);

                // Postgres
                //string connString = "Server=localhost;database=TestDB;user id=postgres;password=postgres";
                //IPersistenceConfigurer configurer = PostgreSQLConfiguration.Standard.ConnectionString(connString);

                // SQL Server 2008
                //string connString = @"data source=.\SQLEXPRESS;initial catalog=TestDB;Integrated Security=True;";
                //IPersistenceConfigurer configurer = MsSqlConfiguration.MsSql2008.ConnectionString(connString);

                return Fluently.Configure()
                               .Database(configurer)
                               .Mappings(m => m.FluentMappings.Add(typeof(TestTblMap))
                               //.ExportTo(@"C:\delme\")
                               )
                               .ExposeConfiguration(BuildSchema)
                               .BuildSessionFactory();
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        private static void BuildSchema(NHibernate.Cfg.Configuration config)
        {
            //new SchemaExport(config).Create(true, true);
            new SchemaUpdate(config).Execute(true, true);
        }

        public static void AddRow(string stringValue, int intValue, DateTime datetimeValue, bool boolValue, string stringValue2)
        {
            try
            {
                using (var session = sessionFactory.OpenSession())
                {
                    using (var transaction = session.BeginTransaction())
                    {
                        TestTbl item = new TestTbl();
                        item.BoolValue = boolValue;
                        item.IntValue = intValue;
                        item.StringValue = stringValue;
                        item.DateTimeValue = datetimeValue;
                        //item.StringValue2 = stringValue2; // UNCOMMENT THIS LINE THE SECOND TIME YOU LAUNCH THE APPLICATION
                        session.Save(item);
                        transaction.Commit();
                    }
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        public class TestTbl
        {
            public virtual int Id { get; protected set; }
            public virtual string StringValue { get; set; }
            //public virtual string StringValue2 { get; set; } // UNCOMMENT THIS LINE THE SECOND TIME YOU LAUNCH THE APPLICATION
            public virtual DateTime DateTimeValue { get; set; }
            public virtual int IntValue { get; set; }
            public virtual bool BoolValue { get; set; }
        }

        public class TestTblMap : ClassMap<TestTbl>
        {
            public TestTblMap()
            {
                Table("\"TestTbl\"");
                //Id(x => x.Id).CustomSqlType("Serial").Column("\"Id\"").Not.Nullable(); // use with postgres
                Id(x => x.Id).Column("\"Id\"").Nullable();
                Map(x => x.StringValue).Column("\"StringValue\"").Not.Nullable();
                //Map(x => x.StringValue2).Column("\"StringValue2\"").Nullable(); // UNCOMMENT THIS LINE THE SECOND TIME YOU LAUNCH THE APPLICATION
                Map(x => x.DateTimeValue).Column("\"DateTimeValue\"").Not.Nullable();
                Map(x => x.IntValue).Column("\"IntValue\"");
                Map(x => x.BoolValue).Column("\"BoolValue\"");
            }
        }
    }
}
根据我在互联网上阅读的理解,我期待的是“alter table”而不是“create table”,但除此之外,从未创建过新列,以下insert语句失败,因为缺少带有以下消息的“StringValue2”列:

could not insert: [SchemaUpdatePOC.Program+TestTbl][SQL: INSERT INTO "TestTbl" ("StringValue", "StringValue2", "DateTimeValue", "IntValue", "BoolValue") VALUES (?, ?, ?, ?, ?); select last_insert_rowid()]

SQL logic error or missing database
table TestTbl has no column named StringValue2
我在取消“.ExportTo”(@“C:\delme\”)行注释时得到的NHibernate xml文件是:


非常感谢您的帮助

我刚刚检查了我的概念证明

通过#1:

通过#2: (我注释掉了过程#1中的行,并向我的实体对象添加了一个新的可空列)

在第二关,我得到了

alter table dbo.MyEntity
  add MyNewColumn DATETIME
附加:

我得到了与您相同的结果,直到我将“映射”更改为非分隔值。 如下图所示。 也许这些额外的斜杠会把“比较”搞砸,它会去创建而不是改变

public class TestTblMap : ClassMap<TestTbl>
{
    public TestTblMap()
    {
        Table("TestTbl");
        //Id(x => x.Id).CustomSqlType("Serial").Column("\"Id\"").Not.Nullable(); // use with postgres
        Id(x => x.Id).Column("Id").Nullable();
        Map(x => x.StringValue).Column("StringValue").Not.Nullable();

        Map(x => x.DateTimeValue).Column("DateTimeValue").Not.Nullable();
        Map(x => x.IntValue).Column("IntValue");
        Map(x => x.BoolValue).Column("BoolValue");

        Map(x => x.StringValue2).Column("StringTwoRules").Nullable(); // UNCOMMENT THIS LINE THE SECOND TIME YOU LAUNCH THE APPLICATION
    }
}

没有delimeters(双引号),它就像魅力!谢谢!如果没有delimeters(双引号),它就像SQLite和SQLServer的魅力一样工作!这解决了我的问题!:)使用分隔符的原因是在使用Postgres时保留大小写符号,但正如我所说,我需要使用SQLite。无论如何,这会产生另一个问题:如何在Postgres中保留驼峰大小写符号,同时利用SchemaUpdate?对你的回答有一点需要注意的是,使用postgres我无法设置config.Properties[“prepare_sql”]=“true”;因为它使我无法通过insert语句,但这是另一回事;)谢谢!你需要问一个关于SOF的新问题。没有人会发现这个“隐藏”的问题。我对博士后一无所知。
NHibernate.dll 3.3.3.4000
FluentNHibernate.dll 1.3.0.733
System.Data.SQLite.dll 1.0.93.0 (when using SQLite)
npgsql.dll 2.0.13.91 (when using Postgres)
        new SchemaExport(cfg).Drop(true, true);
        //re-create database
        new SchemaExport(cfg).Create(true, true);
        new SchemaUpdate(cfg).Execute(true, true);
alter table dbo.MyEntity
  add MyNewColumn DATETIME
public class TestTblMap : ClassMap<TestTbl>
{
    public TestTblMap()
    {
        Table("TestTbl");
        //Id(x => x.Id).CustomSqlType("Serial").Column("\"Id\"").Not.Nullable(); // use with postgres
        Id(x => x.Id).Column("Id").Nullable();
        Map(x => x.StringValue).Column("StringValue").Not.Nullable();

        Map(x => x.DateTimeValue).Column("DateTimeValue").Not.Nullable();
        Map(x => x.IntValue).Column("IntValue");
        Map(x => x.BoolValue).Column("BoolValue");

        Map(x => x.StringValue2).Column("StringTwoRules").Nullable(); // UNCOMMENT THIS LINE THE SECOND TIME YOU LAUNCH THE APPLICATION
    }
}
    private static void BuildSchema(NHibernate.Cfg.Configuration config)
    {

        // set parameters here like this:
        config.Properties["show_sql"] = "true";
        config.Properties["prepare_sql"] = "true";



        //new SchemaExport(config).Drop(true, true);
        ////re-create database
        //new SchemaExport(config).Create(true, true);


        new SchemaUpdate(config).Execute(true, true);
    }