简体   繁体   English

nHibernate通过SQLite支持外键

[英]nHibernate Support for Foreign Keys with SQLite

nHibernate does not appear to support foreign keys with SQLite. nHibernate似乎不支持SQLite的外键。 By default foreign keys are not supported in SQLite either, but may be enabled by running PRAGMA foreign_keys = ON. 默认情况下,SQLite也不支持外键,但是可以通过运行PRAGMA foreign_keys = ON来启用外键。 But I don't know how or where to do this in my nHibernate code. 但是我不知道如何在我的nHibernate代码中执行此操作。

Any ideas on how to get nHibernate to work with foreign keys in SQLite? 关于如何使nHibernate与SQLite中的外键一起使用的任何想法? I found an old work-around which did not work ( Does SQLite coupled with NHibernate support referential integrity / foreign keys? ). 我发现一个旧的解决方法不起作用( SQLite与NHibernate结合使用是否支持参照完整性/外键? )。

Here is my code. 这是我的代码。 The mapping is done with hbm xml files, but that shouldn't matter. 映射是通过hbm xml文件完成的,但这无关紧要。 The error returned is "SQL logic error or missing database near "constraint": syntax error". 返回的错误是“ SQL逻辑错误或在“约束”附近缺少数据库:语法错误”。

namespace ConsoleApp
{
    public class Employee
    {
        public virtual int Id { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual string Email { get; set; }
        public virtual int DepartmentId { get; set; }
        public virtual Department Department { get; set; }
    }

    public class Department
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual List<Employee> Employees { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var cfg = new Configuration();
            cfg.DataBaseIntegration(x =>
            {
                x.ConnectionString = "data source=:memory:";
                x.Driver<SQLite20Driver>();
                x.Dialect<MsSql2012Dialect>();
                x.ConnectionReleaseMode = ConnectionReleaseMode.OnClose;

            });
            cfg.AddAssembly(Assembly.GetExecutingAssembly());

            var sessionFactory = cfg.BuildSessionFactory();
            var session = sessionFactory.OpenSession();

            new SchemaExport(cfg).Execute(true, true, false, session.Connection, null);
        }
    }
}

the reason why you get "SQL logic error or missing database\\r\\nnear \\"constraint\\": syntax error" is because you have set the wrong dialect. 之所以收到“ SQL逻辑错误或缺少数据库\\ r \\ nnear \\” constraint \\”:语法错误”,是因为您设置了错误的方言。

You are using the MsSql2012 dialect so NHibernate will create SQL statements thinking that database supports certain features, but because it is different database, it doesn't support them. 您正在使用MsSql2012方言,因此NHibernate将创建SQL语句,认为数据库支持某些功能,但是由于它是不同的数据库,因此不支持它们。

There is no pragma, because MsSQL doesn't have pragma, so use SQLiteDialect instead: 没有编译指示,因为MsSQL没有编译指示,所以请改用SQLiteDialect:

cfg.DataBaseIntegration(x =>
{
  x.ConnectionString = "data source=:memory:";
  x.Driver<SQLite20Driver>();
  x.Dialect<SQLiteDialect>();
  x.ConnectionReleaseMode = ConnectionReleaseMode.OnClose;
});

Documentation : 说明文件

You should always set the dialect property to the correct NHibernate.Dialect.Dialect subclass for your database. 您应该始终将Dialect属性设置为数据库的正确NHibernate.Dialect.Dialect子类。

SQLite SQLite的
NHibernate.Dialect.SQLiteDialect NHibernate.Dialect.SQLiteDialect
Set driver_class to NHibernate.Driver.SQLite20Driver for System.Data.SQLite provider for .NET 2.0. 将.NET 2.0的System.Data.SQLite提供程序的driver_class设置为NHibernate.Driver.SQLite20Driver。

SchemaExport SQL Commands for MsSQLDialect: MsSQLDialect的SchemaExport SQL命令:

if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FK20E4895FB0DFE40D]') AND parent_object_id = OBJECT_ID('Employee')) alter table Employee  drop constraint FK20E4895FB0DFE40D
if exists (select * from dbo.sysobjects where id = object_id(N'Employee') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Employee
if exists (select * from dbo.sysobjects where id = object_id(N'Department') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Department

create table Employee (
    Id INT not null,
    FirstName NVARCHAR(255) null,
    LastName NVARCHAR(255) null,
    Email NVARCHAR(255) null,
    DepartmentId INT null,
    primary key (Id)
)

create table Department (
    Id INT not null,
    Name NVARCHAR(255) null,
    primary key (Id)
)

alter table Employee
    add constraint FK20E4895FB0DFE40D
    foreign key (DepartmentId)
    references Department

It will fail here, because SQLite doesn't support alter table add constraint syntax (=here is the syntax error message). 此处将失败,因为SQLite不支持alter table add约束语法(=这是语法错误消息)。

SchemaExport SQL Commands for SQLiteDialect: 用于SQLiteDialect的SchemaExport SQL命令:

PRAGMA foreign_keys = OFF

drop table if exists Employee

drop table if exists Department

PRAGMA foreign_keys = ON

create table Employee (
   Id INT not null,
   FirstName TEXT,
   LastName TEXT,
   Email TEXT,
   DepartmentId INT,
   primary key (Id),
   constraint FK20E4895FB0DFE40D foreign key (DepartmentId) references Department
)

create table Department (
   Id INT not null,
   Name TEXT,
   primary key (Id)
)

The pragma is turned off while deleting and then reenabled again. 删除时将关闭编译指示,然后再次重新启用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM