首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用SubSonic和sqlite插入主键值存在问题,因为SubSonic认为列是AutoIncrement或非AutoIncrement

问使用SubSonic和sqlite插入主键值存在问题,因为SubSonic认为列是AutoIncrement或非AutoIncrement
EN

Stack Overflow用户
提问于 2010-02-17 17:47:08
回答 3查看 1.1K关注 0票数 1

我使用的是SubSonic 2.2和sqlite,在使用非AUTOINCREMENT的整数主键列处理表时遇到了一个问题。根据常见问题的说法:

如果将表的某一列声明为整数主键,则每当您在该表的该列中插入NULL时,该NULL将自动转换为大于该列对表中所有其他行的最大值的整数,如果该表为空,则转换为1。

因此sqlite认为这些列有时是自动递增的(即在提供空值时)。问题是SubSonic认为它们总是自动递增。

在我的应用程序中,我的ID值是从远程数据库生成的,所以我不想在sqlite中自动生成它们。这不成问题:我只需在此表中创建记录时提供值。但是,当我使用亚音速的sonic.exe自动生成DAL时,主键列被设置为AutoIncrement = true。这似乎意味着我不能设置ID列-亚音速的ActiveHelper.GetInsertCommand()忽略它,因为它认为它是自动生成的。

它确定其是否为自动增量的行在SubSonic.SQLiteDataProvider.GetTableSchema()中:

代码语言:javascript
复制
column.AutoIncrement = Convert.ToBoolean(row["PRIMARY_KEY"]) && GetDbType(row["DATA_TYPE"].ToString()) == DbType.Int64;

我想解决办法要么是

  • 不对在其他地方生成的键使用整数主键列,或
  • 修改模板,这样这类列就不会被设置为AutoIncrement = true。这意味着SubSonic永远不会将它们作为自动增量来处理,所以我需要小心,以后不要期望获得自动生成的值。不幸的是,我认为模板中不可能很容易地确定该列是否真的是AUTOINCREMENT,所以也许我不得不做一些丑陋的硬编码.

还有其他的想法或建议吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-02-17 18:54:12

不幸的是,我们的SQLiteDataProvider假设如果它是Int64 PK,那么它就是自动增量。我现在正在查看源代码(我没有编写这个提供程序),我可以看到加载模式的方式是使用Connection.GetSchema -它使用构建的System.Data.Common.DbConnection来获取表的模式。

这在大多数情况下是次优的,因为它返回的信息有限。在这种情况下-它并没有告诉我们列是否是AUTOINCREMENT。也许有一种更好的方法来询问SQLite表上的元信息--但不幸的是它没有被使用。

简短的回答:如果可以的话,定义一个新的PK,并使用另一个键作为参考。

票数 2
EN

Stack Overflow用户

发布于 2010-02-20 09:06:04

正如我之前提到的,我在去年12月注册了一个修订过的SQLiteDataProvider。请检查SQLiteDataProvider.cs中的第407行,您有:

//自动增量检测现在可以在最近的System.Data.SQLite中使用。1.0.60.0 -- paul column.AutoIncrement =Convert.ToBoolean(行“AUTOINCREMENT”);

在周围的行中还有其他一些改进和bug修复。新代码从未添加到github的主项目发行版中--我想,我不太关注这个项目。除了文件级锁定之外,SQLite一直是一个很好的提供程序。我有一个国产的System.Data.SQLite版本,它使用了SQLite的新外键特性,官方版本应该在本月完成吗?

以下是修改后的版本:SQLiteDataProvider.cs

顺便说一句,如果您需要从sql server转换,请查看此项目:

将Server数据库转换为SQLite DB http://www.codeproject.com/KB/database/convsqlservertosqlite.aspx

票数 1
EN

Stack Overflow用户

发布于 2010-02-22 09:12:32

由于文件锁定,我发现不能使用用CreateConnection编写的SqlDataProvider。现在的CreateConnection在SQLiteDataProvider中是错误的,因为它忽略了新的连接字符串。

System.Data.SQLite文档说:“您可以创建多个线程,而这些线程可以创建自己的SQLiteConnection和后续对象来访问数据库。多个线程到同一个数据库文件的多个连接是完全可以接受的,并且行为是可以预测的。”

因此,我尝试了以下几点,这是非常排他性的。使用由线程id和连接字符串键键确定的连接字典。但是所有的单元测试都通过了,包括大多数事务(需要更好的测试)。我又写了几个事务测试,带有关键部分锁,我认为它可能是线程安全的,只是需要更现实的测试。

代码语言:javascript
复制
private Dictionary<string, SQLiteConnection> threadConnectionTable = new Dictionary<string, SQLiteConnection>();

public override DbConnection CreateConnection(string newConnectionString)
{
    SQLiteConnection conn;
    string connKey = "t" + Thread.CurrentThread.ManagedThreadId + "__" + newConnectionString;
    if(threadConnectionTable.ContainsKey(connKey))
    {
        conn = threadConnectionTable[connKey];
        if(conn.State != ConnectionState.Open)
            conn.Open();
        return conn;
    }
    conn = new SQLiteConnection(newConnectionString);
    conn.Open();
    threadConnectionTable[connKey] = conn;
    return conn;
}



private Object thisLock = new Object();

[Test]
[ThreadedRepeat(10)]
public void MultiThreadRepeat()
{
    lock(thisLock)
    {
        var qcc = new QueryCommandCollection();
        int threadId = Thread.CurrentThread.ManagedThreadId;
        Debug.WriteLine("MultiThreadRepeat: thread id = " + threadId);
        int count = 0;
        for(int n = 0; n < 10; n++)
        {
            Query qry1 = new Query(Product.Schema);
            qry1.QueryType = QueryType.Update;
            qry1.AddWhere(Product.Columns.ProductID, n);
            qry1.AddUpdateSetting("ProductName", threadId + ": unit test ");
            QueryCommand cmd = qry1.BuildUpdateCommand();
            qcc.Add(cmd);
            count++;
        }
        DataService.ExecuteTransaction(qcc);
        var p1 = new Product(1);
        Assert.AreEqual(p1.ProductName, threadId + ": unit test ", StringComparison.InvariantCultureIgnoreCase);
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2283063

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档