WPF MVVM, SqlSugar access MySQL batch by batch

Install-Package NewtonSoft.Json;
Install-Package MySQL.Data;
Install-Package SqlSugar;

 

mysql> show create table t1;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                                                                          |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `id` int NOT NULL AUTO_INCREMENT,
  `firstname` varchar(100) NOT NULL DEFAULT '',
  `lastname` varchar(100) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `fn_ln_index` (`firstname`,`lastname`)
) ENGINE=InnoDB AUTO_INCREMENT=458600003 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

 

image

 

 

public class BookService
{
    private readonly SqlSugarScope db;
    public BookService()
    {
        db = DatabaseConfig.GetSqlSugarClient();
    }

    public Book GetBookById(int id)
    {
        return db.Queryable<Book>().Where(x => x.Id == id).First();
    }

    public List<Book> GetBooksRangeList(int startId, int endId)
    {
        return db.Queryable<Book>().Where(x => x.Id >= startId && x.Id <= endId).ToList();
    }

    public List<Book> GetUsersByConditions(string fnValue, string lnValue)
    {
        return db.Queryable<Book>()
            .Where(x => string.Equals(x.FirstName, fnValue, StringComparison.InvariantCultureIgnoreCase)
            || string.Equals(x.LastName, lnValue, StringComparison.InvariantCultureIgnoreCase)).ToList();
    }


    public (List<Book> Data, int Total) GetBooksPaged(int pageIdx, int pageSize)
    {
        int total = 0;
        var data = db.Queryable<Book>()
            .ToPageList(pageIdx, pageSize, ref total);
        return (data, total);
    }
}


  private void NextCommandExecuted(object? obj)
  {
      ++batchIdx;
      BooksCollection = new ObservableCollection<Book>(bookService.GetBooksRangeList(batchIdx * batchSize+1, (batchIdx + 1) * batchSize));
      MainTitle = $"Loaded from{batchIdx * batchSize + 1} to {(batchIdx + 1) * batchSize}";
  }

 

image

 

 

 

 

image

 

 

 

 

image

 

image

 

 

<Application x:Class="WpfApp33.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApp33"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <Style TargetType="Button">
            <Setter Property="FontSize" Value="50"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="Red"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Application.Resources>
</Application>


<Window x:Class="WpfApp33.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:WpfApp33"
        mc:Ignorable="d"
        WindowState="Maximized"
        Title="{Binding MainTitle}" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <DataGrid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
                  ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                  VirtualizingPanel.IsVirtualizing="True"
                  VirtualizingPanel.VirtualizationMode="Recycling"
                  VirtualizingPanel.CacheLengthUnit="Item"
                  VirtualizingPanel.CacheLength="2,2"
                  ScrollViewer.IsDeferredScrollingEnabled="True"
                  ScrollViewer.CanContentScroll="True"
                  AutoGenerateColumns="False"
                  CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid Width="{Binding DataContext.GridWidth,RelativeSource={RelativeSource AncestorType=Window}}"
                                  Height="{Binding DataContext.GridHeight,RelativeSource={RelativeSource AncestorType=Window}}">
                                <Grid.Resources>
                                    <Style TargetType="TextBlock">
                                        <Setter Property="FontSize" Value="30"/>
                                        <Style.Triggers>
                                            <Trigger Property="IsMouseOver" Value="True">
                                                <Setter Property="FontSize" Value="50"/>
                                                <Setter Property="Foreground" Value="Red"/>
                                            </Trigger>
                                        </Style.Triggers>
                                    </Style>
                                </Grid.Resources>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Grid.Column="0" Text="{Binding Id}"/>
                                <TextBlock Grid.Column="1" Text="{Binding FirstName}"/>
                                <TextBlock Grid.Column="2" Text="{Binding LastName}"/>
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
        <Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Button Grid.Column="0" Content="Prev" Command="{Binding PrevCommand}"/>
            <Button Grid.Column="1" Content="Next" Command="{Binding NextCommand}"/>
        </Grid>
    </Grid>
</Window>

using SqlSugar;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
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;

namespace WpfApp33
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var vm = new MainVM();
            this.DataContext = vm;
            this.Loaded += async (s, e) =>
            {
                await vm.InitBooksCollection();
                vm.GridWidth = this.ActualWidth;
                vm.GridHeight= this.ActualHeight/10;
            };
        }
    }

    public class MainVM : INotifyPropertyChanged
    {
        int batchSize = 1_000_000;
        int batchIdx = 0;
        private BookService bookService;

        public MainVM()
        {
            bookService = new BookService();
            PrevCommand = new DelCommand(PrevCommandExecuted);
            NextCommand = new DelCommand(NextCommandExecuted);
        }

        private void NextCommandExecuted(object? obj)
        {
            ++batchIdx;
            BooksCollection = new ObservableCollection<Book>(bookService.GetBooksRangeList(batchIdx * batchSize+1, (batchIdx + 1) * batchSize));
            MainTitle = $"Loaded from{batchIdx * batchSize + 1} to {(batchIdx + 1) * batchSize}";
        }

        private void PrevCommandExecuted(object? obj)
        {
            if (--batchIdx >= 0)
            {
                BooksCollection = new ObservableCollection<Book>(bookService.GetBooksRangeList(batchIdx * batchSize+1, (batchIdx + 1) * batchSize));
                MainTitle = $"Loaded from{batchIdx * batchSize + 1} to {(batchIdx + 1) * batchSize}";
            }
        }

        public async Task InitBooksCollection()
        {
            BooksCollection = new ObservableCollection<Book>(bookService.GetBooksRangeList(batchIdx * batchSize+1, (batchIdx + 1) * batchSize));
            MainTitle = $"Loaded from{batchIdx * batchSize + 1} to {(batchIdx + 1) * batchSize}";
        }

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


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


        private double gridWidth;
        public double GridWidth
        {
            get
            {
                return gridWidth;
            }
            set
            {
                if(value != gridWidth)
                {
                    gridWidth = value;
                    OnPropertyChanged();
                }
            }
        }

        private double gridHeight;
        public double GridHeight
        {
            get
            {
                return gridHeight;
            }
            set
            {
                if(value!=gridHeight)
                {
                    gridHeight = value;
                    OnPropertyChanged();
                }
            }
        }

        private string mainTitle;
        public string MainTitle
        {
            get
            {
                return mainTitle; 
            }
            set
            {
                if(value!=mainTitle)
                {
                    mainTitle = value;
                    OnPropertyChanged();
                }
            }
        }

        public ICommand PrevCommand { get; set; }
        public ICommand NextCommand { get; set; }
    }


    [SugarTable("t1")]
    public class Book
    {
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }


    public class BookService
    {
        private readonly SqlSugarScope db;
        public BookService()
        {
            db = DatabaseConfig.GetSqlSugarClient();
        }

        public Book GetBookById(int id)
        {
            return db.Queryable<Book>().Where(x => x.Id == id).First();
        }

        public List<Book> GetBooksRangeList(int startId, int endId)
        {
            var resultList= db.Queryable<Book>().Where(x => x.Id >= startId && x.Id <= endId).ToList();
            if (resultList == null || !resultList.Any())
            {
                MessageBox.Show("No proper data set retrieved!");
                return null;
            }
            return resultList;
        }

        public List<Book> GetUsersByConditions(string fnValue, string lnValue)
        {
            return db.Queryable<Book>()
                .Where(x => string.Equals(x.FirstName, fnValue, StringComparison.InvariantCultureIgnoreCase)
                || string.Equals(x.LastName, lnValue, StringComparison.InvariantCultureIgnoreCase)).ToList();
        }


        public (List<Book> Data, int Total) GetBooksPaged(int pageIdx, int pageSize)
        {
            int total = 0;
            var data = db.Queryable<Book>()
                .ToPageList(pageIdx, pageSize, ref total);
            return (data, total);
        }
    }


    public class DatabaseConfig
    {
        public static SqlSugarScope GetSqlSugarClient()
        {
            return new SqlSugarScope(new ConnectionConfig()
            {
                ConnectionString = "Server=localhost;Database=databasename;Uid=uidvalue;Pwd=passwordValue",
                DbType = DbType.MySql,
                IsAutoCloseConnection = true,
                InitKeyType = InitKeyType.Attribute
            });
        }
    }


    public class DelCommand : ICommand
    {
        private Action<object?> execute;
        private Predicate<object?> canExecute;

        public DelCommand(Action<object?> executeValue, Predicate<object?> canExecuteValue = null)
        {
            execute = 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(parameter);
        }
    }
}

 

posted @ 2025-10-17 09:46  FredGrit  阅读(4)  评论(0)    收藏  举报