2010-08-24 120 views
3

我使用的是SubSonic 3.0.0.3,我似乎无法获得ActiveRecord .tt文件来识别和生成我的SQLite数据库中的外键和关系代码。SubSonic不识别SQLite外键

我认为它产生的一切都很好,但在看了其他片段后,看起来应该有更多生成的代码,而不仅仅是我的每个表格的ActiveRecord.csStructs.cs中的单个类。寻找Structs.csIsForeignKey总是false每列,即使是我有一个外键定义的。此外,每个生成的ActiveRecord类中的每个Foreign Keys区域都是空的。

我在我的项目中使用VS2008引用了SubSonic 3.0.0.3,System.Data.SQLite 1.0.66.0和System.Data.SQLite.Linq 2.0.38.0。我使用SQLite Expert Personal 3.1.0.2076创建了数据库。我制作了一些虚拟表格来测试SubSonic如何处理一个:许多和许多:许多关系。这里的DDL SQLite的专家吐出来为我的小数据库:

CREATE TABLE [Person] (
[PersonID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
[PersonName] TEXT NOT NULL, 
[PersonAge] INT NOT NULL 
); 

CREATE TABLE [Group] (
[GroupID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
[GroupName] TEXT NOT NULL, 
[GroupDescription] TEXT NOT NULL 
); 

CREATE TABLE [Dog] (
    [DogID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
    [PersonID] INT NOT NULL CONSTRAINT [DogPersonFK] REFERENCES [Person]([PersonID]) ON DELETE CASCADE ON UPDATE CASCADE, 
    [DogName] TEXT NOT NULL); 

CREATE TABLE [GroupPersons] (
    [GroupID] INTEGER NOT NULL CONSTRAINT [GroupPersonToGroupFK] REFERENCES [Group]([GroupID]) ON DELETE CASCADE ON UPDATE CASCADE, 
    [PersonID] INTEGER NOT NULL CONSTRAINT [GroupPersonToPersonFK] REFERENCES [Person]([PersonID]) ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT [sqlite_autoindex_GroupPersons_1] PRIMARY KEY ([GroupID], [PersonID])); 

我知道外键被启用,并在数据库的工作 - SQLite的专家说,他们是在和我在一个地方更改的数据,就像人的是PersonID它确实会更改Dog和GroupPersons表中的PersonID。我尝试将数据库重新添加到项目中,'运行自定义工具'以使.tt文件再次执行,甚至删除它们并将它们添加回来。我可以得到一个简单的项目来执行简单的查询和插入,但是我现在试着改变一个Person,Dog或Group和x.Save()的主键,但是System.Data.SQLite抛出了一个异常所有三个,在Save()上说SQLite error near "WHERE":syntax error.

对于我下一步应该尝试做的任何建议?

+0

在'x.Save()'函数中使用的查询是什么? – MPelletier 2010-08-24 03:41:35

回答

5

看来,FKTables每个属性表未在文件“SQLite.ttinclude”中分配。所以我添加了一些代码行,并设法生成外键代码:

第16行(var schema = conn。的getSchema( “列”);),插入:

var schemaForeignKeys = conn.GetSchema("FOREIGNKEYS"); 

线后29(tbl.Name =行[ “TABLE_NAME”]的ToString();),插入:

tbl.FKTables = new List<FKTable>(); 
var foreignKeyTables = schemaForeignKeys.Select("TABLE_NAME='" + tbl.Name + "'"); 
foreach (var foreignKeyTable in foreignKeyTables) { 
    FKTable foreignKey = new FKTable(); 
    foreignKey.ThisTable = foreignKeyTable["TABLE_NAME"].ToString(); 
    foreignKey.ThisColumn = foreignKeyTable["FKEY_FROM_COLUMN"].ToString(); 
    foreignKey.OtherTable = foreignKeyTable["FKEY_TO_TABLE"].ToString(); 
    foreignKey.OtherColumn = foreignKeyTable["FKEY_TO_COLUMN"].ToString(); 
    foreignKey.OtherClass = CleanUp(foreignKey.OtherTable); 
    foreignKey.OtherQueryable = foreignKey.OtherClass; 
    tbl.FKTables.Add(foreignKey); 
} 

和后(col.IsNullable =行[ “IS_NULLABLE”]的ToString()== “真”)线53,插入件:

col.IsForeignKey = tbl.FKTables.Any(x => x.ThisColumn == col.Name); 

这是为生成外键码。

此外,当您必须删除一个列中有一列作为另一个表中的外键的记录时,您可能会遇到问题?例如: Person(Id,Name) Dog(Id,#PersonId) 如果您已将#PersonId外键on-delete操作设置为“SET TO NULL”,则此操作将失效,因为禁用了外键支持默认情况下在SQLite 3.6.23.1(由Data.SQLite 1.0.66.0使用的版本)。 要启用外键的支持,你必须与每个连接执行此命令:

PRAGMA foreign_keys = ON; 

现在,这不是由Data.SQLite支持,但它(在1.0.67.0版本,http://sqlite-dotnet2.cvs.sourceforge.net/viewvc/sqlite-dotnet2/SQLite.NET/System.Data.SQLite/SQLiteConnection.cs?r1=1.80&r2=1.81)。

因此,您必须等待发布,或者您可以(像我一样)下载Data.SQLite源代码并编译最新版本。它对我很好。

祝你好运。 对不起,我的英语:)

+0

你在SO上有一个好的开始! – MPelletier 2010-08-26 11:15:52

1

我想说明这一点。似乎就在眼前两个问题:

  • 亚音速不承认你的外键
  • x.Save()函数在发送错误信息。

SQLite将自行实施参照完整性,所以虽然Subsonic看不到外部引用,但SQLite会这样做,这就是更新过程的原因。亚音速不会驱动SQLite,它正在自我驱动,这很好。

我在试图学习什么SubSonic 确实。同时,我有这个假设:表格定义没有正确解析。如果x.Save()使用自动生成的SQL,则可能是这两个问题实际上只是一个。

为了验证(或无效)这个假设,你可以尝试定义表这样,给外键表的属性,具体领域的不属性:

CREATE TABLE [Dog] (
    [DogID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
    [PersonID] INTEGER NOT NULL, 
    [DogName] TEXT NOT NULL, 
    FOREIGN KEY ([PersonID]) REFERENCES [Person]([PersonID]) ON DELETE CASCADE ON UPDATE CASCADE); 

CREATE TABLE [GroupPersons] (
    [GroupID] INTEGER NOT NULL, 
    [PersonID] INTEGER NOT NULL, 
    FOREIGN KEY ([GroupID]) REFERENCES [Group]([GroupID]) ON DELETE CASCADE ON UPDATE CASCADE, 
    FOREIGN KEY ([PersonID]) REFERENCES [Person]([PersonID]) ON DELETE CASCADE ON UPDATE CASCADE, 
    PRIMARY KEY ([GroupID], [PersonID]));