最近做了一個小網站,用到了一個使用sql server 2005的.net cms系統,但是現在我所買虛擬主機的服務商,不給虛擬主機提供sql server服務了,那就轉資料庫吧,轉啥好呢,思來想去,access?剛入行時候用了很久,簡單夠用,不過實在提不起興趣了,sqlite?嗯...還沒用過,只是簡單看過介紹,聽說性能還不錯,那就試試吧,等等,不知道虛擬主機支持不支持?!百度!然而一大堆沒啥用處的提問和回答,也許可能大概是我搜索的關鍵詞不對,懶得管了,年齡大了,沒有那個勁兒了,實踐出真理,先上手試試驗證一下吧,說干就干
先查查怎么在本地創建和管理資料庫,然后選擇使用了SQLiteStudio這個軟體,然后新建個test資料庫->隨便插條資料->然后在vs創建個test web專案->資料庫檔案扔進去->新建個頁面,查下資料顯示到頁面->本地運行,ok!,發布,->上傳虛擬主機,懷著稍稍激動的心情,打開網址,ok!完全可以!
這么簡單嗎?nonono,運行之前還是有點小小的障礙的:
首先專案需要用到System.Data.SQLite.dll,到sqlite官網下一個吧,http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
然后添加參考,參考之后,還需要連接字串,搜索(ss)! 嗯,和access很像,附個例子:
<add name="ConnectionString" connectionString="Data Source=|DataDirectory|testdb.db;Version=3;Pooling=true;FailIfMissing=false" providerName="System.Data.SQLite" />
這樣就可以運行了!具體的引數還有不少,ss一下,根據需求自己設定,
然后開始改cms吧,首先是轉資料庫,一看表,我尼瑪,好多表,自己一個一個建嗎?想想都想打消折騰的念頭了,有沒有什么工具可以借助呢?ss一下,還真有!
SQL server To SQLite DB Convert 這是一位叫liron.levi老外寫的,專案地址:https://www.codeproject.com/Articles/26932/Convert-SQL-Server-DB-to-SQLite-DB
簡直神器,界面如下

作者還給出了源代碼,在源代碼中可以看到資料型別對應的轉換
/// <summary>
/// Used when creating the CREATE TABLE DDL. Creates a single row
/// for the specified column.
/// </summary>
/// <param name="col">The column schema</param>
/// <returns>A single column line to be inserted into the general CREATE TABLE DDL statement</returns>
private static string BuildColumnStatement(ColumnSchema col, TableSchema ts, ref bool pkey)
{
StringBuilder sb = new StringBuilder();
sb.Append("\t[" + col.ColumnName + "]\t");
// Special treatment for IDENTITY columns
if (col.IsIdentity)
{
if (ts.PrimaryKey.Count == 1 && (col.ColumnType == "tinyint" || col.ColumnType == "int" || col.ColumnType == "smallint" ||
col.ColumnType == "bigint" || col.ColumnType == "integer"))
{
sb.Append("integer PRIMARY KEY AUTOINCREMENT");
pkey = true;
}
else
sb.Append("integer");
}
else
{
if (col.ColumnType == "int")
sb.Append("integer");
else
{
sb.Append(col.ColumnType);
}
if (col.Length > 0)
sb.Append("(" + col.Length + ")");
}
if (!col.IsNullable)
sb.Append(" NOT NULL");
if (col.IsCaseSensitivite.HasValue && !col.IsCaseSensitivite.Value)
sb.Append(" COLLATE NOCASE");
string defval = StripParens(col.DefaultValue);
defval = DiscardNational(defval);
_log.Debug("DEFAULT VALUE BEFORE [" + col.DefaultValue + "] AFTER [" + defval + "]");
if (defval != string.Empty && defval.ToUpper().Contains("GETDATE"))
{
_log.Debug("converted SQL Server GETDATE() to CURRENT_TIMESTAMP for column [" + col.ColumnName + "]");
sb.Append(" DEFAULT (CURRENT_TIMESTAMP)");
}
else if (defval != string.Empty && IsValidDefaultValue(defval))
sb.Append(" DEFAULT " + defval);
return sb.ToString();
} View Code
然后就用這個工具把cms的sql server資料庫轉換成sqlite資料庫檔案,直接扔進cms專案中,
這樣就行了嗎?當然還有作業要做,原來專案中操作sql server的類別庫也要換成sqlite的,sql陳述句也要做相應的轉換,下面就挑一些重點的說一說:
先說資料型別吧:
由于在工具的源代碼中,主鍵不管什么型別的int轉成sqlite都用的integer,有需求的可以自己改代碼,不過最好要熟悉sqlite的資料型別,下面列出我在專案中所遇到的主要型別轉換
| sql server | c# | sqlite | c# |
| int | new SqlParameter("@id", SqlDbType.Int,4) | integer | new SQLiteParameter("@id", DbType.Int64,8) |
| nvarchar | new SqlParameter("@id", SqlDbType.NVarChar,50) | nvarchar | new SQLiteParameter("@id", DbType.String,50) |
| decimal | new SqlParameter("@id", SqlDbType.Decimal) | numeric | new SQLiteParameter("@id", DbType.Decimal) |
| tinyint | new SqlParameter("@id", SqlDbType.TinyInt,1) | smallint | new SQLiteParameter("@id", DbType.Int16,1) |
| ntext | new SqlParameter("@id", SqlDbType.NText) | text | new SQLiteParameter("@id", DbType.String) |
| datetime | new SqlParameter("@id", SqlDbType.DateTime) | datetime | new SQLiteParameter("@id", DbType.DateTime) |
| Image | new SqlParameter("@fs", SqlDbType.Image) | Binary | new SQLiteParameter("@fs", DbType.Binary) |
代碼資料型別轉換之后,就剩除錯修改sql陳述句了,下面列出我在專案中遇到的比較主要的轉換
1、top陳述句,在sqlite中要使用limit,和mysql差不多,例如
sql:select top 10 * from table_1 sqlite:select * from table_1 limit 10
2、在插入一條資料后,要獲取最新的id
sql:select @@IDENTITY; sqlite:select LAST_INSERT_ROWID();
3、計算時間差
sql:where datediff(d,field_time,getdate())>=0 sqlite:where JULIANDAY(datetime('now','localtime'))-JULIANDAY(field_time)>=0
4、分頁
sql:2005以上一般使用ROW_NUMBER() select * from ( select row_number() over(order by id) as rows,* ) as t where rows between PageIndex*PageSize and PageIndex*PageSize+PageSize sqlite:用 limit offset select * from table_1 limit PageSize offset (PageIndex- 1) * PageSize
5、最讓人抓狂的是修改表部分的差異
這一部分單獨再寫一篇吧
時間不早了,來自老年人的嘆息.....
第二天了,附上修改表的文章鏈接:sqlite修改表、表欄位等與sql server的不同之處
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/103499.html
標籤:C#
上一篇:C# .NET的BinaryFormatter、protobuf-net、Newtonsoft.Json以及自己寫的序列化方法序列化效率和序列化后的檔案體積大小對比
下一篇:資料結構之佇列and堆疊總結分析
