WPF SQLite SQLiteStudio

1.Download SQLiteStudio via  below url and then install step by step

https://release-assets.githubusercontent.com/github-production-release-asset/117119718/433e0deb-ce58-4e38-8152-b361a9934502?sp=r&sv=2018-11-09&sr=b&spr=https&se=2026-05-21T10%3A51%3A08Z&rscd=attachment%3B+filename%3DSQLiteStudio-3.4.21-windows-x64-installer.exe&rsct=application%2Foctet-stream&skoid=96c2d410-5711-43a1-aedd-ab1947aa7ab0&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skt=2026-05-21T09%3A50%3A36Z&ske=2026-05-21T10%3A51%3A08Z&sks=b&skv=2018-11-09&sig=LtzOcE4WE9G6s8Ufnci2ltgUQ%2Bjkly%2BL%2FVsckC5plUs%3D&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmVsZWFzZS1hc3NldHMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwia2V5Ijoia2V5MSIsImV4cCI6MTc3OTM1ODkwNSwibmJmIjoxNzc5MzU3MTA1LCJwYXRoIjoicmVsZWFzZWFzc2V0cHJvZHVjdGlvbi5ibG9iLmNvcmUud2luZG93cy5uZXQifQ.UOZtNR6qWrhwt7L0DS0hQuBPCnmPuSdu2P0zDLmmBzU&response-content-disposition=attachment%3B%20filename%3DSQLiteStudio-3.4.21-windows-x64-installer.exe&response-content-type=application%2Foctet-stream

2.

Install-Package Microsoft.Data.Sqlite.Core
Install-Package SQLitePCLRaw.bundle_e_sqlite3

 

3.

private void OpenSqliteConnection(string dbName="")
{
    SQLitePCL.Batteries.Init();
    if (string.IsNullOrWhiteSpace(dbName))
    {
        dbName = $"DB_{DateTime.Now.ToString("yyyyMM")}";
    }
    string connStr = $"Data Source={dbName}.db";
    sqliteConn = new SqliteConnection(connStr);
    sqliteConn.Open();
}


private void InsertIntoSQLiteCmdExecuted(object? obj)
{
    var dg = obj as DataGrid;
    if (dg != null && dg.Items != null && dg.Items.Count>0)
    {
        var itemsList = dg.Items.Cast<Book>()?.ToList();

        InsertIntoItemsToSQLite(itemsList);
    }
}

private void InsertIntoItemsToSQLite(List<Book>? booksList)
{
    if(booksList==null || !booksList.Any())
    {
        return;
    }
    string dbName = $"DB_{DateTime.Now.ToString("yyyyMM")}";
    string tableName = $"Book_{DateTime.Now.ToString("yyyyMMdd")}";
    CreateTableIfNotExists(dbName,tableName);
    InsertIntoTableInBatch(tableName, booksList, 100000);
}

private void InsertIntoTableInBatch(string tableName, List<Book> booksList, int batchSize=10000)
{
    int booksCnt = booksList.Count;
    int batches = (booksCnt + batchSize - 1) / batchSize;
    for(int i=0;i<batches;i++)
    {
        int start_idx=i*batchSize;
        int end_idx=Math.Min((i+1)*batchSize, booksCnt);
        var batchBooks=booksList.Skip(start_idx).Take(batchSize).ToList();
        StringBuilder insertBuilder = new StringBuilder();
        insertBuilder.Append($"insert into {tableName} (name,isbn,author,abstract,content,comment,summary,title,topic) values ");

        foreach (var bk in batchBooks)
        {
            insertBuilder.Append($"('{bk.Name}','{bk.ISBN}','{bk.Author}','{bk.Abstract}','{bk.Content}','{bk.Comment}','{bk.Summary}','{bk.Title}','{bk.Topic}'),");
        }
        string insertSQL = insertBuilder.ToString();
        insertSQL = insertSQL.Substring(0, insertSQL.Length - 1);
        ExecuteSQL(insertSQL);
        System.Diagnostics.Debug.WriteLine($"{DateTime.Now},Insert between First Id:{batchBooks.FirstOrDefault()?.Id} and Last Id:{batchBooks.LastOrDefault()?.Id} into {tableName} successfully");
    }
}

private void CreateTableIfNotExists(string dbName = "DB_202605",string tableName="Book_20260521")
{
    string useDbSql = $"use {dbName}";
    string createTableSQL = $"create table if not exists {tableName} (id integer primary key autoincrement," +
          "name varchar(100) not null default '',ISBN varchar(100) not null default '',Author varchar(100) not null default '',"
          + "Abstract varchar(100) not null default '',Content varchar(100) not null default '',Comment varchar(100) not null default '',"
      + "Summary varchar(100) not null default '',Title varchar(100) not null default '',Topic varchar(100) not null default '')";
    ExecuteSQL(createTableSQL);
    System.Diagnostics.Debug.WriteLine($"{DateTime.Now},create table {tableName} successfully");
}

private void ExecuteSQL(string sql)
{
    using(SqliteCommand cmd=new SqliteCommand(sql,sqliteConn))
    {
        cmd.ExecuteNonQuery();
    }
}

private void OpenSqliteConnection(string dbName="")
{
    SQLitePCL.Batteries.Init();
    if (string.IsNullOrWhiteSpace(dbName))
    {
        dbName = $"DB_{DateTime.Now.ToString("yyyyMM")}";
    }
    string connStr = $"Data Source={dbName}.db";
    sqliteConn = new SqliteConnection(connStr);
    sqliteConn.Open();
}

 

 

2026-05-21 20:18:20,create table Book_20260521 successfully
2026-05-21 20:18:20,Insert between First Id:27152001 and Last Id:27252000 into Book_20260521 successfully
2026-05-21 20:18:21,Insert between First Id:27252001 and Last Id:27352000 into Book_20260521 successfully
2026-05-21 20:18:21,Insert between First Id:27352001 and Last Id:27452000 into Book_20260521 successfully
2026-05-21 20:18:21,Insert between First Id:27452001 and Last Id:27552000 into Book_20260521 successfully
2026-05-21 20:18:22,Insert between First Id:27552001 and Last Id:27652000 into Book_20260521 successfully
2026-05-21 20:18:22,Insert between First Id:27652001 and Last Id:27752000 into Book_20260521 successfully
2026-05-21 20:18:22,Insert between First Id:27752001 and Last Id:27852000 into Book_20260521 successfully
2026-05-21 20:18:23,Insert between First Id:27852001 and Last Id:27952000 into Book_20260521 successfully
2026-05-21 20:18:23,Insert between First Id:27952001 and Last Id:28052000 into Book_20260521 successfully
2026-05-21 20:18:23,Insert between First Id:28052001 and Last Id:28152000 into Book_20260521 successfully

 

 

 

 

 

 

 

image

 

 

 

<Window x:Class="WpfApp34.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp34"
        mc:Ignorable="d"
        Title="{Binding MainTitle}" WindowState="Maximized">
    <Window.DataContext>
        <local:MainVM/>
    </Window.DataContext>
    <Grid>
        <DataGrid ItemsSource="{Binding BooksCollection}"
                  IsReadOnly="True"
                  SelectionMode="Extended"
                  VirtualizingPanel.IsVirtualizing="True"
                  VirtualizingPanel.VirtualizationMode="Recycling"
                  VirtualizingPanel.CacheLengthUnit="Item"
                  VirtualizingPanel.CacheLength="5,5"
                  ScrollViewer.IsDeferredScrollingEnabled="True"
                  ScrollViewer.CanContentScroll="True"
                  UseLayoutRounding="True"
                  SnapsToDevicePixels="True"
                  AutoGenerateColumns="True"
                  CanUserAddRows="False"
                  EnableRowVirtualization="True"
                  EnableColumnVirtualization="True"
                 >
            <DataGrid.Resources>
                <Style TargetType="DataGridRow">
                    <Setter Property="FontSize" Value="30"/>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="FontSize" Value="40"/>
                            <Setter Property="Foreground" Value="Red"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.Resources>
            <DataGrid.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Refresh Data"
                              Command="{Binding DataContext.RefreshDataCmd,RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"/>

                    <MenuItem Header="Insert Into SQLite"
                              Command="{Binding DataContext.InsertIntoSQLiteCmd,RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"
                              CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}},Path=PlacementTarget}"/>
                </ContextMenu>
            </DataGrid.ContextMenu>
        </DataGrid>
    </Grid>
</Window>


using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data.Common;
using System.Diagnostics.Eventing.Reader;
using System.Net;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Data.Sqlite;
using Newtonsoft.Json;
using SQLitePCL;

namespace WpfApp34
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class MainVM : INotifyPropertyChanged
    {
        string requestUrl = "http://localhost:7777/BookService.svc/getbookslist?cnt=";
        private HttpClient client;
        private DispatcherTimer tmr;
        public ICommand InsertIntoSQLiteCmd { get; set; }
        public ICommand RefreshDataCmd { get; set;  }

        SqliteConnection sqliteConn;

        public MainVM()
        {
            if (!DesignerProperties.GetIsInDesignMode(new DependencyObject()))
            {
                InitCmds();
                OpenSqliteConnection();
                client = new HttpClient();
                Task.Run(async () =>
                {
                    await LoadDataFromServiceAsync();
                });
            }
        }

        private void InitCmds()
        {
            InsertIntoSQLiteCmd = new DelCmd(InsertIntoSQLiteCmdExecuted);
            RefreshDataCmd = new DelCmd(RefreshDataCmdExecuted);
        }

        private void RefreshDataCmdExecuted(object? obj)
        {
            Task.Run(async () =>
            {
                await LoadDataFromServiceAsync();
            });
        }

        private void InsertIntoSQLiteCmdExecuted(object? obj)
        {
            var dg = obj as DataGrid;
            if (dg != null && dg.Items != null && dg.Items.Count>0)
            {
                var itemsList = dg.Items.Cast<Book>()?.ToList();

                InsertIntoItemsToSQLite(itemsList);
            }
        }

        private void InsertIntoItemsToSQLite(List<Book>? booksList)
        {
            if(booksList==null || !booksList.Any())
            {
                return;
            }
            string dbName = $"DB_{DateTime.Now.ToString("yyyyMM")}";
            string tableName = $"Book_{DateTime.Now.ToString("yyyyMMdd")}";
            CreateTableIfNotExists(dbName,tableName);
            InsertIntoTableInBatch(tableName, booksList, 100000);
        }

        private void InsertIntoTableInBatch(string tableName, List<Book> booksList, int batchSize=10000)
        {
            int booksCnt = booksList.Count;
            int batches = (booksCnt + batchSize - 1) / batchSize;
            for(int i=0;i<batches;i++)
            {
                int start_idx=i*batchSize;
                int end_idx=Math.Min((i+1)*batchSize, booksCnt);
                var batchBooks=booksList.Skip(start_idx).Take(batchSize).ToList();
                StringBuilder insertBuilder = new StringBuilder();
                insertBuilder.Append($"insert into {tableName} (name,isbn,author,abstract,content,comment,summary,title,topic) values ");

                foreach (var bk in batchBooks)
                {
                    insertBuilder.Append($"('{bk.Name}','{bk.ISBN}','{bk.Author}','{bk.Abstract}','{bk.Content}','{bk.Comment}','{bk.Summary}','{bk.Title}','{bk.Topic}'),");
                }
                string insertSQL = insertBuilder.ToString();
                insertSQL = insertSQL.Substring(0, insertSQL.Length - 1);
                ExecuteSQL(insertSQL);
                System.Diagnostics.Debug.WriteLine($"{DateTime.Now},Insert between First Id:{batchBooks.FirstOrDefault()?.Id} and Last Id:{batchBooks.LastOrDefault()?.Id} into {tableName} successfully");
            }
        }

        private void CreateTableIfNotExists(string dbName = "DB_202605",string tableName="Book_20260521")
        {
            string useDbSql = $"use {dbName}";
            string createTableSQL = $"create table if not exists {tableName} (id integer primary key autoincrement," +
                  "name varchar(100) not null default '',ISBN varchar(100) not null default '',Author varchar(100) not null default '',"
                  + "Abstract varchar(100) not null default '',Content varchar(100) not null default '',Comment varchar(100) not null default '',"
              + "Summary varchar(100) not null default '',Title varchar(100) not null default '',Topic varchar(100) not null default '')";
            ExecuteSQL(createTableSQL);
            System.Diagnostics.Debug.WriteLine($"{DateTime.Now},create table {tableName} successfully");
        }

        private void ExecuteSQL(string sql)
        {
            using(SqliteCommand cmd=new SqliteCommand(sql,sqliteConn))
            {
                cmd.ExecuteNonQuery();
            }
        }

        private void OpenSqliteConnection(string dbName="")
        {
            SQLitePCL.Batteries.Init();
            if (string.IsNullOrWhiteSpace(dbName))
            {
                dbName = $"DB_{DateTime.Now.ToString("yyyyMM")}";
            }
            string connStr = $"Data Source={dbName}.db";
            sqliteConn = new SqliteConnection(connStr);
            sqliteConn.Open();
        }

        private async Task LoadDataFromServiceAsync(int cnt = 1000000)
        {
            MainTitle = $"{DateTime.Now},loading from service...";
            string jsonStr = await client.GetStringAsync($"{requestUrl}{cnt}");
            if (!string.IsNullOrWhiteSpace(jsonStr))
            {
                List<Book>? bksList = JsonConvert.DeserializeObject<List<Book>>(jsonStr);
                if (bksList != null && bksList.Any())
                {
                    BooksCollection = new ObservableCollection<Book>(bksList);
                    MainTitle = $"{DateTime.Now},loaded {BooksCollection.Count()} items,{GetMem()}";
                }
            }
        }

        private string GetMem()
        {
            return $"memory {System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64 / 1024 / 1024:N2} M";
        }


        private static long idx = 0;
        public static long GetIncrementIdx()
        {
            return Interlocked.Increment(ref idx);
        }

        private string mainTitle = $"{DateTime.Now},loading...";
        public string MainTitle
        {
            get
            {
                return mainTitle;
            }
            set
            {
                if (value != mainTitle)
                {
                    mainTitle = value;
                    OnPropertyChanged();
                }
            }
        }


        private ObservableCollection<Book> booksCollection;
        public ObservableCollection<Book> BooksCollection
        {
            get
            {
                return booksCollection;
            }
            set
            {
                if (value != booksCollection)
                {
                    booksCollection = value;
                    OnPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "")
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(propName));
        }
    }

    public class DelCmd : ICommand
    {
        private Action<object?>? execute;
        private Predicate<object?>? canExecute;
        public DelCmd(Action<object?>? executeValue, Predicate<object?>? canExecuteValue = null)
        {
            execute = executeValue ?? throw new ArgumentNullException(nameof(executeValue));
            canExecute = canExecuteValue;
        }

        public event EventHandler? CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }

        public bool CanExecute(object? parameter)
        {
            return canExecute == null ? true : canExecute(parameter);
        }

        public void Execute(object? parameter)
        {
            execute?.Invoke(parameter);
        }
    }

    [DataContract]
    public class Book
    {
        [DataMember]
        public long Id { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string ISBN { get; set; }
        [DataMember]
        public string Author { get; set; }
        [DataMember]
        public string Abstract { get; set; }
        [DataMember]
        public string Comment { get; set; }
        [DataMember]
        public string Content { get; set; }
        [DataMember]
        public string Summary { get; set; }
        [DataMember]
        public string Title { get; set; }
        [DataMember]
        public string Topic { get; set; }
    }
}

 

 

SELECT * FROM sqlite_master;

select * from Book_20260521;

select count(id) from Book_20260521;

 

string createTableSQL = $"create table if not exists {tableName} (id integer primary key autoincrement," +
      "name varchar(100) not null default '',ISBN varchar(100) not null default '',Author varchar(100) not null default '',"
      + "Abstract varchar(100) not null default '',Content varchar(100) not null default '',Comment varchar(100) not null default '',"
  + "Summary varchar(100) not null default '',Title varchar(100) not null default '',Topic varchar(100) not null default '')";
 private void InsertIntoTableInBatch(string tableName, List<Book> booksList, int batchSize=10000)
 {
     int booksCnt = booksList.Count;
     int batches = (booksCnt + batchSize - 1) / batchSize;
     for(int i=0;i<batches;i++)
     {
         int start_idx=i*batchSize;
         int end_idx=Math.Min((i+1)*batchSize, booksCnt);
         var batchBooks=booksList.Skip(start_idx).Take(batchSize).ToList();
         StringBuilder insertBuilder = new StringBuilder();
         insertBuilder.Append($"insert into {tableName} (name,isbn,author,abstract,content,comment,summary,title,topic) values ");

         foreach (var bk in batchBooks)
         {
             insertBuilder.Append($"('{bk.Name}','{bk.ISBN}','{bk.Author}','{bk.Abstract}','{bk.Content}','{bk.Comment}','{bk.Summary}','{bk.Title}','{bk.Topic}'),");
         }
         string insertSQL = insertBuilder.ToString();
         insertSQL = insertSQL.Substring(0, insertSQL.Length - 1);
         ExecuteSQL(insertSQL);
         System.Diagnostics.Debug.WriteLine($"{DateTime.Now},Insert between First Id:{batchBooks.FirstOrDefault()?.Id} and Last Id:{batchBooks.LastOrDefault()?.Id} into {tableName} successfully");
     }
 }

 

 

image

 

posted @ 2026-05-21 20:23  FredGrit  阅读(6)  评论(0)    收藏  举报