問題の概要
実現したいこと
ファイルピッカーで選択した画像を保存ボタンを押下して画像のバイナリデータを「gazouByte.db3」に保存する。
「Get All GazouList」を押下してdb内に存在する画像の「Id」「ファイル名」「拡張子」をCollectionViewを用いて「MainPage」に表示する。
問題点
「gazouByte.db3」にバイナリデータが保存されない。
「Get All GazouList」を押下しても「got all file list」しか表示されず、「Id」「ファイル名」「拡張子」が表示されない。
※Table[("gazouByte")]は作成されていることを「DB Browser for SQlite」で確認しています。
[1]: https://i.sstatic.net/4aow2gVL.png
再現手順
問題が発生する具体的な手順。
- VisualStudio2022にてWindowsMachineを用いてデバッグを開始する。
- 「ファイルを選択する」を押してファイルピッカーの起動を行う。そこから画像(jpg/png)を選択。
- 「ファイルを選択する」の下に画像のプレビューを確認
- 「ファイルを保存する」を押し、赤字で「file saved」が表示されることを確認。
- 「DB Browser for SQlite」でデータ閲覧を行う。テーブルは作成されているが、データが保存されていない。
コード
using WorkReview.Models; using System.Collections.Generic; using Microsoft.Maui.Controls; using WorkReview.ViewModels; using System.Runtime.CompilerServices; namespace WorkReview.Views { public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); BindingContext = new MainViewModel(); } public void OnGetAllGazouClicked(object sender, EventArgs args) { List<GazouByte> gazouByte = App.GazouByteRepo.GetAllGazouBytes(); statusMessage.Text = "got all file list"; } public void OnFileSaveClicked(object sender, EventArgs args) { (BindingContext as MainViewModel).SaveGazouToDataBase(); //BindingVontextのインスタンスをもちいて.Save~メソッドを実行している statusMessage.Text = "file saved"; } public async void OnFileSelectClicked(object sender, EventArgs args) { try { var result = await FilePicker.PickAsync(); var fileExtension = result.ContentType; var fileName = result.FileName; if (result != null) { if (result.FileName.EndsWith("jpg", StringComparison.OrdinalIgnoreCase) || result.FileName.EndsWith("png", StringComparison.OrdinalIgnoreCase)) { using (var stream = await result.OpenReadAsync()) { using (var memoryStream = new MemoryStream())///using(var)はUsingステートメント,{}内の処理が終わったときにリソースが開放される { await stream.CopyToAsync(memoryStream); //memoryStreamに保存されたデータをViewModelの該当箇所へ送る (BindingContext as MainViewModel).gazouExtension = fileExtension; (BindingContext as MainViewModel).gazouName = fileName; (BindingContext as MainViewModel).gazouBinary = memoryStream.ToArray(); var previewStream = new MemoryStream(memoryStream.ToArray()); userPreview.Source = ImageSource.FromStream(() => previewStream); } } } else { statusMessage.Text = "Unsupported file type."; } } } catch (Exception ex) { statusMessage.Text = $"Error selecting file: {ex.Message}"; } } } }
Repositryはこちら
using SQLite; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WorkReview.Models; namespace WorkReview.Models { public class GazouByteRepositry { string _gazoudbPath; public string GazouStatusMessage { get; set; } private SQLiteConnection gazouconn; public GazouByteRepositry(string gazoudbPath) { _gazoudbPath = gazoudbPath; } private void Init() //dbに接続後テーブル作成 create table when connect db.3 { if (gazouconn is not null) return; gazouconn = new SQLiteConnection(_gazoudbPath); gazouconn.CreateTable<GazouByte>(); } public void AddNewGazouByte(string gazouName, byte[] gazouBinary, string gazouExtension)//画像データをDBへ挿入 add image data to db.3 { ArgumentNullException.ThrowIfNull(gazouName, nameof(gazouExtension)); ArgumentNullException.ThrowIfNull(gazouBinary, nameof(gazouBinary)); ArgumentNullException.ThrowIfNull(gazouName, nameof(gazouName)); int gazouResult = 0; try { Init(); gazouResult = gazouconn.Insert(new GazouByte { GazouName = gazouName, GazouBinary = gazouBinary, GazouExtension = gazouExtension }); Console.WriteLine($"Insert result: {gazouResult}"); GazouStatusMessage = string.Format("{0} record(s) added (GazouName: {1})", gazouResult, gazouName); } catch (Exception ex) { GazouStatusMessage = string.Format("Failed to add {0}. Error: {1}", gazouName, ex.Message); } } public List<GazouByte> GetAllGazouBytes()//テーブルを取得 get table then create list for controll-view .MainPage { try { Init(); return gazouconn.Table<GazouByte>().ToList(); } catch (Exception ex) { GazouStatusMessage = string.Format("Failed to retrieve data .{0}", ex.Message); } return new List<GazouByte>(); } } }
テーブルはこちら
using SQLite; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit; namespace WorkReview.Models; [Table("gazouByte")] public class GazouByte { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string GazouName { get; set; } public byte[] GazouBinary { get; set; } //画像のバイナリ用 Binary fo image to db.3 public string GazouExtension { get; set; } }
期待している動作
- デバッグを開始した段階でテーブル「"gazouByte"」がappdataに作成される。
- 「ファイルを選択する」を押すことによってファイルピッカーが起動、そこから画像ファイルを選択。
- ファイルピッカーが閉じると「ファイルを保存する」の下に選択した画像がプレビュー表示される。
- その後、「ファイルを保存する」によってMemoryStreamの画像が「gazouByte.db3」へ保存され、「Get All GazouList」を押下することで「gazouByte.db3」に保存されたファイルの「Id」「ファイル名」「拡張子」がCollectionViewに表示される。
試したこと
- GazouByteRepositry.AddNewGazouByte メソッドで例外処理が正しく行われていることを確認しました。
- Table[("gazouByte")]が作成されていることを「DB Browser for SQlite」で確認しました。
- 画像を選択し、保存ボタンを押した後、再度画像を選択せずに保存ボタンを押すとSystem.NullReferenceExceptionが発生することを確認しました。
エラーメッセージやログ
画像は保存されませんでしたが、エラーメッセージが出ることはありませんでした。
環境
Windows 11 Home (23H2)
VisualStudio Community 2022 preview 17.11.0 Preview 4.0
Microsoft.Maui.Controls 8.0.80
Microsoft .NET SDK 8.0.107(x64)
SQlitePCLRaw.bundle_green 2.1.9
sqlite-net-pcl 1.9.172
CommunityToolkit.Mvvm 8.2.2
補足情報
コードの全体は次のURLの「WorkReview/WorkReview/」の中にあります
回答1件
あなたの回答
tips
プレビュー