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