.NET MAUIとEntityFramework

C# コンピュータ
C#
データベースのSqliteをEntityFrameworkを使ってアクセスしてみました。

ReactivePropertyをインストール

NuGetでReactivePropertyをインストール
Visual Studio 2022のメニュー→「プロジェクト」→「NuGetパッケージの管理」
ReactiveProperty
System.Reactive
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Sqlite.Core
SQLitePCLRaw.bundle_green
sqlite-net-pcl
検索しインストール

ソースコード

ファイル名:MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiSQLiteSample.MainPage">
    <ScrollView>
        <VerticalStackLayout>
            <CollectionView
                ItemsSource="{Binding Items}"
                SelectedItem="{Binding SelectedItem.Value}"
                SelectionMode="Single">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Grid Padding="10">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="40" />
                                <RowDefinition Height="40" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="80" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Label Grid.Column="0"
                                    Text="{Binding Id}"
                                    FontSize="18" />
                            <Label Grid.Column="1"
                                    Text="{Binding Name}"
                                    FontSize="18" />
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
            <Label
                Text="{Binding SelectedName.Value}"
                FontSize="18"/>
            <Button
                Text="Add"
                Margin="8"
                Command="{Binding OnAddCliked}" />
            <Button
                Text="Remove"
                Margin="8"
                Command="{Binding OnRemoveCliked}" />
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

ファイル名:MainPage.xaml.cs

namespace MauiSQLiteSample;

public partial class MainPage : ContentPage
{
    ViewModel _vm;

    public MainPage()
    {
        InitializeComponent();
        this.Loaded += MainPage_Loaded;
    }

    private void MainPage_Loaded(object sender, EventArgs e)
    {
        _vm = new ViewModel();
        this.BindingContext = _vm;
    }
}

ファイル名:ViewModel.cs

using Reactive.Bindings;
using SQLitePCL;

namespace MauiSQLiteSample;

public class ViewModel
{
    public ReactiveCollection<Card> Items { get; set; } = new ReactiveCollection<Card>();
    public ReactiveProperty<Card> SelectedItem { get; } = new ReactiveProperty<Card>();
    public ReactiveProperty<string> SelectedName { get; } = new ReactiveProperty<string>("");
    public ReactiveCommand OnAddCliked { get; set; } = new ReactiveCommand();
    public ReactiveCommand OnRemoveCliked { get; set; } = new ReactiveCommand();
    public ReactiveCommand OnUpdateCliked { get; set; } = new ReactiveCommand();
    int i = 0;


    public ViewModel()
    {
        var db = new MyDbContext();

        // テーブル作成
        db.Database.EnsureCreated();

        // レコード件数が0の場合
        if (!db.Card.Any())
        {
            // 追加
            db.Add(new Card { Name = "TARO" });
            db.Add(new Card { Name = "HANA" });
            db.Add(new Card { Name = "MINA" });
            db.SaveChanges();
        }
        // レコードの取得
        foreach (var r in db.Card)
        {
            // ListViewに追加
            Items.Add(r);
        }


        SelectedItem.Subscribe((o) =>
        {
            SelectedName.Value = o?.Name;
        });

        // 追加
        OnAddCliked.Subscribe((o) =>
        {
            i++;
            var card = new Card { Name = String.Format("No.{0}", i) };
            // テーブルに追加
            db.Add(card);
            db.SaveChanges();

            Items.Clear();
            foreach (var r in db.Card)
            {
                Items.Add(r);
            }
        });

        // 削除
        OnRemoveCliked.Subscribe((o) =>
        {
            if (SelectedItem.Value != null)
            {
                db.Remove(SelectedItem.Value);
                db.SaveChanges();
                SelectedItem.Value = null;

                Items.Clear();
                foreach (var r in db.Card)
                {
                    Items.Add(r);
                }
            }
        });
    }
}

ファイル名:Card.cs

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MauiSQLiteSample;


public class Card
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public long Id { get; set; }
    public string Name { get; set; } = "";
}

ファイル名:MyDbContext.cs

using Microsoft.EntityFrameworkCore;

namespace MauiSQLiteSample;

public class MyDbContext : DbContext
{
    public DbSet<Card> Card => Set<Card>();
    public string DbPath { get; set; } = "";

    public MyDbContext()
    {
        DbPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/sample.db";
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite($"Data Source={DbPath}");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Card>().ToTable("Card");
    }
}

実行

「Add」をクリック

「No.1」が追加された。追加された項目を選択

「Remove」ボタンを押す。

「No.1」が削除された。

感想

画面とDBの両方で追加と削除することが出来ました。

感想2

DBの操作部分をViewModel.csで行っていますが、後のことを考えると別クラスに切りだした方が良いかも。

コメント