首页 > 数据库 >Avalonia通过ef操作sqlite

Avalonia通过ef操作sqlite

时间:2023-05-29 16:57:33浏览次数:70  
标签:sqlite void ef db CreateDbContext var new public Avalonia

首选我们建个MVVM模板的项目,在项目中引入包 Microsoft.EntityFrameworkCore.Sqlite

1、创建实体

public class TodoEntity
{
    public Guid Id { get; set; }

    public string Thing { get; set; }

    public DateTime CreateTime { get; set; }
}

2、创建上下文

ublic class DatabaseContext : DbContext
{
    public DatabaseContext(DbContextOptions<DatabaseContext> options)
        : base(options)
    {
    }
    
    public DbSet<TodoEntity> TodoEntities { get; set; }

    protected override void OnModelCreating(ModelBuilder model)
    {
        model.Entity<TodoEntity>(m =>
        {
            m.ToTable("todo");
            m.Property(c => c.Id);
            m.Property(c => c.Thing).IsRequired();
            m.HasKey(c => c.Id);
        });
    }
}

3、创建Factory

public class DatabaseContextFactory
{
    public DatabaseContext CreateDbContext(string[] args)
    {

        var m = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "todo.db");
        var options = new DbContextOptionsBuilder<DatabaseContext>();
        options.UseSqlite($"Data Source={m};");
        return new DatabaseContext(options.Options);
    }

    public DatabaseContext CreateDbContext() => CreateDbContext(new string[0]);
}

4、启动时创建一下数据库

 public override void OnFrameworkInitializationCompleted()
    {
        if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        {
            desktop.MainWindow = new MainWindow();

            desktop.Startup += OnDesktopOnStartup;
        }

        base.OnFrameworkInitializationCompleted();
    }

    private void OnDesktopOnStartup(object sender, ControlledApplicationLifetimeStartupEventArgs args)
    {
        using var db = new DatabaseContextFactory().CreateDbContext();
        db.Database.EnsureCreated();
    }

5、修改MainWindowViewModel

public class MainWindowViewModel : ViewModelBase
{
    private ObservableCollection<TodoEntity> _todoEntities = new();

    public ObservableCollection<TodoEntity> TodoEntities
    {
        get => _todoEntities;
        set => this.RaiseAndSetIfChanged(ref _todoEntities, value);
    }

    public void Add(string thing)
    {
        using var db = new DatabaseContextFactory().CreateDbContext();
        db.TodoEntities.Add(new TodoEntity()
        {
            Id = new Guid(),
            Thing = thing,
            CreateTime = DateTime.Now
        });
        db.SaveChanges();
    }

    public void Refresh()
    {
        using var db = new DatabaseContextFactory().CreateDbContext();
        var m = db.TodoEntities.ToList();
        TodoEntities.Clear();
        TodoEntities.AddRange(m);
    }
    
    public void Clear()
    {
        TodoEntities.Clear();
        using var db = new DatabaseContextFactory().CreateDbContext();
        var m = db.TodoEntities.ToList();
        db.TodoEntities.RemoveRange(m);
        db.SaveChanges();
    }
}

6、修改MainWindow

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:SqliteEFDemo.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
        Width="500"
        x:Class="SqliteEFDemo.Views.MainWindow"
        x:DataType="vm:MainWindowViewModel"
        Icon="/Assets/avalonia-logo.ico"
        Title="SqliteEFDemo">

    <Design.DataContext>
        <!-- This only sets the DataContext for the previewer in an IDE,
             to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
        <vm:MainWindowViewModel/>
    </Design.DataContext>

    <Grid RowDefinitions="Auto,*">
        <StackPanel Orientation="Horizontal" Spacing="20" Margin="10 0">
            <TextBox Name="Thing" Width="200" />
            <Button Content="Add" x:Name="Add" Click="Add_OnClick"/>
            <Button Content="Refresh" x:Name="Refresh" Click="Refresh_OnClick"/>
            <Button Content="Clear" x:Name="Clear" Click="Clear_OnClick"/>
        </StackPanel>
        
        <StackPanel Orientation="Vertical" Grid.Row="1">
            <ItemsControl Items="{Binding TodoEntities}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Thing}" Margin="20 10"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </StackPanel>
    </Grid>
    
</Window>

7、修改MainWindow.axaml.cs

public partial class MainWindow : Window
{
    private MainWindowViewModel vm;
    public MainWindow()
    {
        InitializeComponent();
        vm = new MainWindowViewModel();
        this.DataContext = vm;
        vm.Refresh();
    }

    private void Add_OnClick(object? sender, RoutedEventArgs e)
    {
        var thingTb = this.FindControl<TextBox>("Thing");

        var s = thingTb?.Text?.Trim();
        if (!string.IsNullOrEmpty(s))
        {
            vm.Add(s);
            vm.Refresh();
        }
    }

    private void Refresh_OnClick(object? sender, RoutedEventArgs e)
    {
        vm.Refresh();
    }

    private void Clear_OnClick(object? sender, RoutedEventArgs e)
    {
        vm.Clear();
    }
}

如果要使用加密的sqlite, 要引入包*SQLitePCLRaw.bundle_e_sqlcipher* , 不然会出现

You specified a password in the connection string, but the native SQLite library 'e_sqlite3' doesn't support encryption. 的报错信息

同时把Factory改为下面这样

public class DatabaseContextFactory
{
    public DatabaseContext CreateDbContext(string[] args)
    {
        var m = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "todo.db");
        var options = new DbContextOptionsBuilder<DatabaseContext>();

        //要加密 需要引入包 SQLitePCLRaw.bundle_e_sqlcipher
        var connStr = new SqliteConnectionStringBuilder()
        {
            DataSource = m,
            Mode = SqliteOpenMode.ReadWriteCreate,
            Password = "admin"
        }.ToString();

        options.UseSqlite(connStr);
        return new DatabaseContext(options.Options);
    }

    public DatabaseContext CreateDbContext() => CreateDbContext(new string[0]);
}

源码地址 https://gitee.com/CRole/my-avalonia-demo/tree/main/SqliteEFDemo

标签:sqlite,void,ef,db,CreateDbContext,var,new,public,Avalonia
From: https://www.cnblogs.com/mchuang/p/17440929.html

相关文章

  • 【Quectel】EC20CEFHLG-128-SNNS物联网 LTE Cat 4 无线通信模块
    产品介绍:EC20是移远通信推出的LTE模块,采用LTE3GPPRel.9技术,支持下行速率100Mbps和上行速率50Mbps,同时在封装上兼容移远通信UMTS/HSPA+UC20模块,实现了从3G网络向4G网络轻松平滑过渡。EC20系列模块包含EC20-A,EC20-C和EC20-E三个版本,使其能够向后兼容现存的EDGE和GSM/GPRS网络,以......
  • Codeforces Round 875 (Div. 2) A-D
    CodeforcesRound875(Div.2)A.TwinPermutationsinta[N];voidsolve(){intn=read();for(inti=1;i<=n;i++)a[i]=read();for(inti=1;i<=n;i++)cout<<n+1-a[i]<<'';cout<<'\n';//puts(ans&g......
  • 如何将word公式粘贴到SiteFactory里面
    ​ 在之前在工作中遇到在富文本编辑器中粘贴图片不能展示的问题,于是各种网上扒拉,终于找到解决方案,在这里感谢一下知乎中众大神以及TheViper。通过知乎提供的思路找到粘贴的原理,通过TheViper找到粘贴图片的方法。其原理为一下步骤:监听粘贴事件;【用于插入图片】获取光标位置;【......
  • linphone-LinphonePreferences.java文件分析
    说明这个文件比较长,主要是对于linphone的配置文件等设置。对于前面文章中文件的调用。其中大多数是对底层的调用设置。功能设置用户信息设置端口号设置显示名称设置密码设置代理设置编码设置编码速率设置DMTF等设置加密解密设置是否使用ipv6设置tunnel设置相机等UML类图LinphonePre......
  • sockjs.js:1603 GET http://localhost/sockjs-node/info?t=1685340190468 net::ER
    vue项目报错不影响运行,但控制台看到这报错,属实不舒服 解决方法:进入\node_modules\sockjs-client\dist\sockjs.js注释1603行   刷新页面,没报错了 ......
  • 什么是 JavaScript 里的循环引用(circular references)
    JavaScript的循环引用(circularreferences)是指在对象之间存在相互引用的情况,形成一个闭环,导致对象无法被完全释放和垃圾回收。循环引用发生在当一个对象的属性或成员引用另一个对象,并且这个被引用的对象又直接或间接地引用回原始对象,从而形成一个循环。当存在循环引用时,JavaScrip......
  • CodeForces 1830C Hyperregular Bracket Strings
    洛谷传送门CF传送门每一步思路都非常自然的题。考虑先从一些简单的case入手。1.\(k=0\)设\(g_i\)为长度为\(i\)的合法括号串数。显然\(\foralli\nmid2,g_i=0\)。对于偶数的\(i\),这是一个经典问题,\(g_i\)就是第\(\frac{i}{2}\)项卡特兰数,因此\(g_i=\bi......
  • vue3学习中使用vue-router@4的问题Invalid VNode type: undefined (undefined)
    首先是按照常规的箭头函数引入的方法,结果报一下错误,且页面报错constHelloWorld=()=>import('../components/HelloWorld.vue'); 解决办法import{defineAsyncComponent}from'vue'constHelloWorld=defineAsyncComponent(()=>import('../components/HelloWorld.vue......
  • Codeforces Round #875 (Div. 2)
    CodeforcesRound#875(Div.2)bilibili:CodeforcesRound#875(Div.2)实况|完成度[4.01/6]A#include<bits/stdc++.h>usingll=longlong;usinguint=unsigned;usingnamespacestd;intTestCase;signedmain(){ for(scanf("%d",&......
  • Firefox 插件:网页剪贴簿(继承自 Firefox 旧版插件 ScrapBook X)
    Firefox插件:网页剪贴簿(继承自Firefox旧版插件ScrapBookX)获取网页至本地或后端服务器供检索、组织、加注、编辑。https://addons.mozilla.org/zh-CN/firefox/addon/webscrapbook/ 网页剪贴簿(WebScrapBook)可以忠实撷取网页内容,支援多种储存格式与客制化设定,还可以对撷......