EF6不支持sqlite Code First解决方案

最近需要项目中需要用到sqlite,项目中其他的功能都是EF+sqlserver实现的数据访问。于是,想用EF来访问sqlite,两个比较麻烦的地方。

第一:EF连接sqlite配置文件需要手动改一下

<entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v13.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />//这里通过nuget添加sqlite的EF的dll后,生成的是:System.Data.SQLite.EF6,改成现在这样就行了。
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite.EF6" />
      <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
      <remove invariant="System.Data.SQLite" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
    </DbProviderFactories>
  </system.data>

第二:EF6默认不支持sqlite Code First生成数据库,需要自己扩展。

public partial class SqliteDataModels : DbContext
    {
        private string _dbPath;
        public SqliteDataModels(string path)
            : base(new SQLiteConnection
            {
                ConnectionString = new SQLiteConnectionStringBuilder
                {
                    DataSource = path,
                    ForeignKeys = false,
                    BinaryGUID = false,
                }.ConnectionString
            }, true)
        {
            _dbPath = path;
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();//
            Database.SetInitializer(new SqliteContextInitializer<SqliteDataModels>(_dbPath, modelBuilder));//这句话是关键。自定义数据库上下文初始化设置
            base.OnModelCreating(modelBuilder);
        }

        public virtual DbSet<t_analysisBooks> t_analysisBooks { get; set; }
        public virtual DbSet<t_GeneraLedgerStatistics> t_GeneraLedgerStatistics { get; set; }
        public virtual DbSet<t_LedgerClassificationChart> t_LedgerClassificationChart { get; set; }
    }

    class SqliteContextInitializer<T> : IDatabaseInitializer<T>
       where T : DbContext
    {
        bool _dbExists;
        DbModelBuilder _modelBuilder;

        public SqliteContextInitializer(string dbPath, DbModelBuilder modelBuilder)
        {
            _dbExists = File.Exists(dbPath);
            _modelBuilder = modelBuilder;
        }

        public void InitializeDatabase(T context)
        {
            if (_dbExists)
                return;

            var model = _modelBuilder.Build(context.Database.Connection);

            using (var xact = context.Database.BeginTransaction())
            {
                try
                {
                    CreateDatabase(context.Database, model);
                    xact.Commit();
                }
                catch (Exception ex)
                {
                    xact.Rollback();
                    throw;
                }
            }
        }

        private void CreateDatabase(Database db, DbModel model)
        {
            const string tableTmpl = "CREATE TABLE [{0}] (\n{1}\n);";
            const string columnTmpl = "    [{0}] {1} {2}"; // name, type, decl    

            foreach (var type in model.StoreModel.EntityTypes)
            {
                var defs = new List<string>();
                //主键
                var keys = type.KeyProperties.Select(x => x.Name).ToList();

                foreach (var p in type.Properties)
                {
                    var decls = new HashSet<string>();
                    //创建列autoincrement
                    if (keys.Contains(p.Name.ToString()))
                    {
                        decls.Add("INTEGER PRIMARY KEY Autoincrement");
                        defs.Add(string.Format(columnTmpl, p.Name, "", string.Join(" ", decls)));
                    }
                    else
                    {
                        if (!p.Nullable)
                            decls.Add("NOT NULL");
                        defs.Add(string.Format(columnTmpl, p.Name, p.TypeName, string.Join(" ", decls)));
                    }
                }
                //创建表
                var sql = string.Format(tableTmpl, type.Name, string.Join(",\n", defs));
                db.ExecuteSqlCommand(sql);
            }
        }
    }
时间: 2024-10-28 22:14:08

EF6不支持sqlite Code First解决方案的相关文章

EF6 Code First 完美支持Sqlite

要想EF6 Code First 模式支持Sqlite 得有一下几步: 一.需要安装 sqlite-netFx451-setup-bundle-x86-2013-1.0.92.0.exe 来让VS添加Ado.net 时有sqlite可选 1) 自己去 http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki 下载对应.net 版本的安装文件(*注意下载文件名带bundle,这个才会对vs进行插件支持) 2)安装 要

让EntityFramework6支持SQLite

最近给朋友的小孩做了一个毕业设计.用的是asp.net MVC5 + EntityFramework6 + SQL Server 2008. 结果做好后,朋友说能不能不要数据库,直接运行?顿时让我很纠结,不需要安装数据库但又能运行的,只能考虑单文件的数据库了,比如说Access或是SQLite. 查阅资料后发现Access无法支持EntityFramework的运行,只要考虑SQLite. 经查阅资料发现,SQLite方法发布了对EntityFramework6支持的程序集,在项目中执行如下命令

jquery 1.9版本后不在支持browser 方法的解决方案

今天对jquery 进行升级,导致项目出错,原来在1.9版本之后 jquery 不支持browser 方法了.  官方建议的又不好用,所以我所jquery 原来的代码摘除来,又扩展回去. //解决jquery 1.9版本之后不支持 browser 这里进行了扩展 var a, b; $.uaMatch = function (a) { a = a.toLowerCase(); var b = /(chrome)[ \/]([\w.]+)/.exec(a) || /(webkit)[ \/]([\

android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error(Sqlite code 14): Could not open database,(OS error - 13:Permission denied)

07-24 15:03:14.490 6291-6291/com.tongyan.nanjing.subway E/SQLiteDatabase: Failed to open database '/storage/emulated/0/TYSubway/structure/db/TYSubwayInspcetionNJ.db'. android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error(Sqlite code

E: Sub-process /usr/bin/dpkg returned an error code (1) 解决方案

E: Sub-process /usr/bin/dpkg returned an error code (1) 解决方案 软件版本: 操作系统:ubuntu 10.04 内核版本:Linux version 2.6.32-41-generic 目录: 1. 错误 2. 解决方法 1) 方案一 2) 方案二 3) 方案三 3. 参考资料 1. 错误 在使用 apt-get 安装工具时,无论安装什么软件都会遇到这样子的错误: dpkg: warning: files list file for pa

JSP不支持EL表达式的解决方案

JSP不支持EL表达式的解决方案 EL的全称是Expression Language. 1.在默认情况下,Servlet 2.3 / JSP 1.2是不支持EL表达式的,而Servlet 2.4 / JSP 2.0支持. servlets 2.4这个版本的isELIgnored默认设置为false.所以使用web.xml里用web-app_2_4.xsd声明的时候在JSP页面不用特意声明.如何查看Servlet / JSP的版本?打开tomcat的common/lib 目录下,有两个JAR文件:

让 PowerDesigner 支持 SQLite!

让 PowerDesigner 支持 SQLite! PowerDesigner是一个功能强大的数据库设计软件,最近正在用其设计新系统的数据库,但由于在项目初级阶段,希望使用轻量级的 SQLite 来做测试会比较方便,不过发现 PowerDesigner 里好像没有直接支持 SQLite 的 DBMS,这样所创建的数据表就不能直接在 SQLite 里生成了,感觉不太爽 不过事情总有解决的办法,其实只需要安装上 SQLite 的驱动,就可以让 PowerDesigner 支持直接生成到 SQLit

ie8以下版本(包括ie8)的浏览器不支持html5标签属性解决方案(Modernizr 2.6.2插件的使用)

今天脑抽想用html5标签设计一个网页,我本人用的是火狐浏览器,都弄好后我发现一个很严重的问题,除了ie9以下的浏览器都不能支持html5标签(article,aside,dialog,footer,header,section,footer,nav,figure,menu). 我上网找了好多中方法,有网友说使用 <!--[if lt IE9]> <script> (function() { if (! /*@[email protected]*/ 0) return; var e

.net core加载加密的sqlite文件失败解决方案

.net core加载加密的sqlite文件失败解决方案 ??在项目开发过程中,遇到使用sqlite的场景.在加载加密的sqlite时,连接sqlite时报错,,先用百度查询了下资料,尚未找到对应解决方法,故接着在stackoverflow上查找,找到了解决思路,并已解决问题. 1.开发时所用到的相关内容 1.1相关项目组件 组件名称 版本 Microsoft.NETCore.App 2.1.0 sqlSugarCore 5.0.0.9 1.2 sqlite加密软件 软件名称 版本 SQLite