zoukankan      html  css  js  c++  java
  • 通过EntityFramework操作sqlite(DbFirst)

    记录一下通过 EntityFramework6 来操作sqlite过程
    环境:

    • visual studio 2017
    • .net 4.5
    • Console Application(项目类型)
    • sqlite3
    • navicat for sqlite

    设计数据库

    我使用了 navicat for sqlite 这个图形界面工具来快速生成数据库的;
    非常简单,打开 navicat ,按照下图操作即可

    新建表:
    Entry表(Id为主键,勾选自增),Type_Id为外键.

    EntryType表(Id为主键,勾选自增)

    完事之后点击左上角的保存!

    在visual studio中建立控制台项目,安装必要的nuget包

    打开nuget包管理工具,
    在Browse选项卡中搜索 System.Data.SQLite
    安装相应的nuget包,如图所示

    之后在nuget包管理工具中查看已安装的nuget包
    如下图:

    然后在解决方案浏览器下可以看到App.config文件,

    进去修改一下内容,在 provider 节点下加入下面的内容:
    <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />

    建立 Entity 实体类

    Entry 类 :

    Entry
    namespace MagicMemory.Core.Entities
    {
        public class Entry
        {
            public int Id { get; set; }
            public string Key { get; set; }
            public string Content { get; set; }
            public int? EntryTypeId { get; set; }
            public virtual EntryType Type { get; set; }
        }
    }
    


    这里值得注意的是,Entry实体中有一个外键属性:

    public virtual EntryType Type { get; set; }

    一定要用virtual来修饰,这里不清楚为啥,我也是偶然看见的,不用virual就没用,可能因为是Dbfirst的原因,之前在.net core结合efcore使用的时候并不需要加virtual也行.这里的外键属性,Ef 会自动从数据库里相应的表中给我们映射过来.但是这个外键所在表也必须在 DbContext中作为DbSet<>的泛型参数存在才可以.

    EntryType 类:

    EntryType
    using System;
    

    namespace MagicMemory.Core.Entities
    {
    public class EntryType
    {
    public int Id { get; set; }
    public string Name { get; set; }
    }
    }

    实体类就这两个,差不多可以说明问题了,建立实体类的时候,实体类的属性名一定要和表的字段名相匹配(必须一样才行),名称不一样的话,则需要在属性的上方加一个注解属性 Column("Name").也可以使用fluentApi来进行配置,我跟喜欢这种方式,在DbContext中重写OnModelCreating()方法,对 column 进行配置.

    当实体类型的属性名需要和不同名称的的表中的列进行映射时,可以使用下面的方法.

    protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Blog>()
                .Property(b => b.BlogId)
                .HasColumnName("blog_id");
        }
    

    继承DbContext,建立数据库上下文 xxxContext 类

    EntryContext
    using System.Data.Entity;
    using System.Data.SQLite;
    using MagicMemory.Core.Entities;
    using SQLite.CodeFirst;
    

    namespace MagicMemory.DbStudy
    {
    public class EntryContext:DbContext
    {
    public EntryContext():base(new SQLiteConnection("Data Source=MagicMemory.Db"),true)
    {
    }

        protected override void OnModelCreating(DbModelBuilder builder)
        {
            builder.Entity&lt;Entry&gt;().ToTable(&quot;Entry&quot;);
            builder.Entity&lt;Entry&gt;()
                .Property(e =&gt; e.EntryTypeId)
                .HasColumnName(&quot;EntryTypeId&quot;);
    
            builder.Entity&lt;EntryType&gt;().ToTable(&quot;EntryType&quot;);
    
            builder.Entity&lt;EntryTag&gt;().ToTable(&quot;EntryTagTable&quot;);
            builder.Entity&lt;EntryTag&gt;()
                .Property(t =&gt; t.Name)
                .HasColumnName(&quot;TagName&quot;);
    
            base.OnModelCreating(builder);
    
            Database.SetInitializer(new SqliteDropCreateDatabaseWhenModelChanges&lt;EntryContext&gt;(builder));
        }
    
        public DbSet&lt;Entry&gt; Entry { get; set; }
        public DbSet&lt;EntryType&gt; EntryType { get; set; }
        public DbSet&lt;EntryTag&gt; EntryTag { get; set; }
    }
    

    }

    这里比较重要的是重写了 OnModelCreating() 方法,这个方法里面通过 fluent api的方式定义了实体类的属性和具体的数据库的字段的映射的关系;同时,在默认的构造函数里面,调用基类的构造函数,因为使用sqlite这个数据库,所以将继承了DbConnection的实例: new SQLiteConnection("[连接字符串]") 传递给基类的构造函数,用来连接数据库.

      </div>
  • 相关阅读:
    L2TP协议
    PPP协议
    centos 更新linux内核
    关于GRUB2
    误删除libc.so.6 恢复
    LVS DR模式 负载均衡服务搭建
    进程地址空间分布和可执行文件分布
    centos 开机启动服务
    【netcore基础】ConcurrentDictionary 使用字符串作为key给代码加锁且使用EF事物防止并发调用数据混乱的问题
    【年终总结】个人的2018年年终总结
  • 原文地址:https://www.cnblogs.com/Laggage/p/10618890.html
Copyright © 2011-2022 走看看