我对本地数据库有哪些选择

本文关键字:选择 数据库 | 更新日期: 2023-09-27 18:31:37

我正在创建一个C# WPF应用程序,我想使用本地数据库来存储数据,但是我对使用什么感到非常困惑。我不会存储任何庞大的数据,我希望能够在无需安装任何其他软件(如SQL服务器)的情况下运行该应用程序。我环顾四周,但发现很难找到相关信息。我想过使用SQL服务器紧凑版,但似乎不受支持,似乎也无法在VS2015社区中创建.sdf数据库,.mdf数据库是唯一的选择(我认为需要SQL服务器)。

SQL Server 精简版处于弃用模式,近期没有新版本计划。最新版本 SQL CE 4.0SP1(以及仍处于支持周期中的早期版本)将在其生命周期中继续受支持,Microsoft致力于修复这些版本中发现的任何重大生产阻塞问题。

您能否说明我可以使用哪些选项或将我引用到可以阅读有关此内容的地方?提前谢谢。

我对本地数据库有哪些选择

使用最广泛的解决方案之一是SQLite。它是一个很小但足够强大的嵌入式SQL引擎,它是跨平台的。它存在了很长时间,并且具有 ADO.NET 驱动程序。

使用 SQLite。我们一直在使用它。对于这样的用例,它快速而强大,并且可以由多种语言访问。与常规数据库不同,它不需要额外的进程,并且会产生一个文件,您可以稍后复制该文件。

我建议使用SQLite。通过 nuget 包安装程序将 SQLite dll 添加到项目引用中。使用 SQLite C# 的基本 CRUD 操作示例。

 public class DownloadDatabase
{
    SQLiteConnection sqliteConnection;
    public DownloadDatabase(string dbName)
    {
        string ConnectionString = "Data Source=" + "Absoute path to database store location" + ";Version=3;";
        sqliteConnection = new SQLiteConnection(ConnectionString);
        sqliteConnection.Open();
    }
    public void CreateDB()
    {
        string table = "CREATE TABLE IF NOT EXISTS Downloads ( _id INTEGER  PRIMARY KEY NULL,user_id TEXT  NULL DEFAULT '', target_id TEXT NOT NULL, url TEXT NOT NULL, local_file TEXT NOT NULL,authenticate TEXT NOT NULL DEFAULT '', login TEXT NULL DEFAULT '', password TEXT NULL DEFAULT '', mime_type TEXT NULL DEFAULT '', accept_ranges TEXT NULL DEFAULT '', file_size NUMBER NULL DEFAULT 0, last_modified TEXT NULL DEFAULT '',created TEXT NULL DEFAULT '',initial_start_position NUMBER NULL DEFAULT 0, start_position NUMBER NULL DEFAULT 0, end_position NUMBER NULL DEFAULT 0, progress TEXT NOT NULL,is_paused TEXT NULL ,device_id TEXT NULL, state NUMBER NULL, originID TEXT NULL DEFAULT '');";
        try
        {
            using (SQLiteCommand command = new SQLiteCommand(table, sqliteConnection))
            {
                command.ExecuteNonQuery();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Creating Downloads database failed: " + ex.Message);
        }
    }
    public void UpdateDBAndCreateEntryIfNotExists(DownloadItem item)
    {
        try
        {
            using (SQLiteCommand checkEntryCommand = sqliteConnection.CreateCommand())
            {
                checkEntryCommand.CommandText = "SELECT * FROM Downloads WHERE target_id=@target_id LIMIT 1";
                checkEntryCommand.Parameters.Add(new SQLiteParameter("@target_id", item.targetID));
                using (SQLiteDataReader reader = checkEntryCommand.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        using (SQLiteCommand updatecommand = sqliteConnection.CreateCommand())
                        {
                            double dprogress;
                            if (!Double.TryParse(reader.GetString(16), out dprogress))
                            {
                                dprogress = 0;
                            }
                            if (item.progress != dprogress)
                            {
                                updatecommand.CommandText = "UPDATE Downloads SET last_modified=@last_modified, start_position=@start_position, end_position=@end_position, progress = @progress, is_paused = @is_paused, state = @state WHERE target_id=@target_id";
                                updatecommand.Parameters.Add(new SQLiteParameter("@last_modified", item.lastModified));
                                updatecommand.Parameters.Add(new SQLiteParameter("@start_position", item.startPosition));
                                updatecommand.Parameters.Add(new SQLiteParameter("@end_position", item.endPosition));
                                updatecommand.Parameters.Add(new SQLiteParameter("@progress", item.progress));
                                updatecommand.Parameters.Add(new SQLiteParameter("@target_id", item.targetID));
                                updatecommand.Parameters.Add(new SQLiteParameter("@is_paused", item.isPaused ? "True" : "False"));
                                updatecommand.Parameters.Add(new SQLiteParameter("@state", item.state));
                                updatecommand.ExecuteNonQuery();
                            }
                        }
                    }
                    else
                    {
                        using (SQLiteCommand insertcommand = sqliteConnection.CreateCommand())
                        {
                            insertcommand.CommandText = "INSERT INTO Downloads ( target_id, url,local_file, authenticate, login, password, mime_type, accept_ranges, file_size, last_modified, created, initial_start_position, start_position, end_position, progress, is_paused, device_id, state, originID)  values (@target_id,@url, @local_file, @authenticate,@login,@password,@mime_type,@accept_ranges,@file_size, @last_modified,@created, @initial_start_position,@start_position,@end_position,@progress,@is_paused, @device_id, @state, @originID) ";
                            insertcommand.Parameters.Add(new SQLiteParameter("@target_id", item.targetID));
                            insertcommand.Parameters.Add(new SQLiteParameter("@url", item.url));
                            insertcommand.Parameters.Add(new SQLiteParameter("@local_file", item.localFile));
                            insertcommand.Parameters.Add(new SQLiteParameter("@authenticate", item.authenticate));
                            insertcommand.Parameters.Add(new SQLiteParameter("@login", item.login == null ? "" : item.login));
                            insertcommand.Parameters.Add(new SQLiteParameter("@password", item.password == null ? "" : item.password));
                            insertcommand.Parameters.Add(new SQLiteParameter("@mime_type", item.mimeType));
                            insertcommand.Parameters.Add(new SQLiteParameter("@accept_ranges", item.acceptRanges));
                            insertcommand.Parameters.Add(new SQLiteParameter("@file_size", item.fileSize));
                            insertcommand.Parameters.Add(new SQLiteParameter("@last_modified", item.lastModified));
                            insertcommand.Parameters.Add(new SQLiteParameter("@created", item.created));
                            insertcommand.Parameters.Add(new SQLiteParameter("@initial_start_position", item.initialStartPosition));
                            insertcommand.Parameters.Add(new SQLiteParameter("@start_position", item.startPosition));
                            insertcommand.Parameters.Add(new SQLiteParameter("@end_position", item.endPosition));
                            insertcommand.Parameters.Add(new SQLiteParameter("@progress", item.progress));
                            insertcommand.Parameters.Add(new SQLiteParameter("@is_paused", item.isPaused ? "True" : "False"));
                            insertcommand.Parameters.Add(new SQLiteParameter("@device_id", item.deviceId == null ? "" : item.deviceId));
                            insertcommand.Parameters.Add(new SQLiteParameter("@state", item.state));
                            insertcommand.Parameters.Add(new SQLiteParameter("@originID", item.originID));
                            insertcommand.ExecuteNonQuery();
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Download progress update failed: " + ex.Message);
        }
    }
    public bool DeleteItem(string targetID)
    {
        try
        {
            using (SQLiteCommand deleteCommand = sqliteConnection.CreateCommand())
            {
                string tableName = "";
                tableName = "Downloads";
                deleteCommand.CommandText = "DELETE FROM " + tableName + " WHERE target_id=@target_id";
                deleteCommand.Parameters.Add(new SQLiteParameter("@target_id", targetID));
                deleteCommand.ExecuteReader();
                return true;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Delete item Failed: " + ex.Message);
            return false;
        }
    }
}

您将使用light-ORM和SQLite的组合。它将满足您的所有需求,甚至更多。

对于特定的光ORM,我强调使用Dapper

打开你的Visual Studio添加sqlite和dapper。

下面是一个使用 dapper 的简单数据访问层的示例

public class MyDal
{
    public List<string> GetSomething()
    {
        var strQuery = string.Format(SQLCOMMAND);
        var result = new List<String>();
        using (var con = DbConnection())
        {
            result = con.Query<String>(strQuery).ToList();
        }
        return result;
    }
    public static OleDbConnection DbConnection()
    {
        return new OleDbConnection(myConnectionString);
    }
}
在这种情况下,

我反复成功使用的一种解决方案是不使用任何 DBMS。相反,您可以使用 ADO。NET DataSet直接读取和写入磁盘文件。此方法的一些优点:

  1. 他们可以通过单线调用序列化其结构和数据。
  2. 无需驱动程序/库。数据集在 .NET 中始终受现成支持。
  3. 无需 SQL。使用 LINQ 或数据控件执行筛选/排序等。
  4. 强类型数据集为您提供智能感知支持。

一些缺点:

  1. 没有 SQL 支持。如果需要复杂的查询,此方法可能不起作用。
  2. 不适合大型数据,因为整个数据库将立即加载到内存中。

由于您已经明确提到您需要一个小型本地数据库,因此这些问题可能不会伤害您。

您有很多选择,但也要考虑您的长期需求:

  • 使用 xml,只需将对象序列化/反序列化为本地 xml 文件即可。
  • 同样,序列化为 json 格式 - 它更紧凑且人类可读。
  • 与其安装数据库,不如租用云提供的数据库,如MySQL。只要您的数据很小,开发人员帐户就应该是免费的。使用像实体框架这样的关系ORM作为中间件,这样您就可以轻松尝试不同的数据库。EF6 与 Firebird 配合使用,它理解 xml 文件(如果使用第一个选项)
  • 完全跳过关系数据库,使用像NDatabase这样的OODB。您也应该能够在云中找到它。