C#多项目使用EF访问Sqlite数据库,解决报错Unable to determine the DbProviderFactory type for connection of type ‘Syst

4 篇文章 0 订阅

1 背景

    二次开发,需要在原有程序基础上进行扩展,原有程序使用 EF 框架访问 sqlserver ,需要增加支持 sqlite 数据库访问功能。

2 问题复现

    下面使用一个 Demo 程序来演示 EF 如何访问 SQLite 数据库,同时演示问题复现以及如何解决如下报错问题: Unable to determine the DbProviderFactory type for connection of type 'System.Data.SQLite.SQLiteConnection'. Make sure that the ADO.NET provider is installed or registered in the application config.

2.1 项目结构

    Visual Studio 2019 创建一个 WinForm 以及 ClassLibrary 程序。WinForm 程序为 .NET Framework 4.6 框架,其中从 nuget 添加了 EntityFrameworkClassLibrary1 是类库项目,添加了 EntityFrameworkSystem.Data.SQLite(包括它的依赖) ,如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    Form1 窗体以及 ClassLibrary 的代码如下:

// Fomr1 窗体代码
using ClassLibrary1.DataAccess;
using System;
using System.Linq;
using System.Windows.Forms;

namespace SQLiteForEF
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            using (var db = new Model1())
            {
                dataGridView1.DataSource = db.Database.SqlQuery<Employee>("select * from employee").ToList();
            }

            // 自定义sqlite数据库的数据源
            using (var db = Model2.Instance)
            {
                dataGridView2.DataSource = db.Database.SqlQuery<Employee2>("select * from employee").ToList();
            }

            // 使用config配置文件中sqlite的数据源
            using (var db = new Model2())
            {
                dataGridView2.DataSource = db.Database.SqlQuery<Employee2>("select * from employee").ToList();
            }
        }
    }
}
// Employee 实体
namespace ClassLibrary1.DataAccess
{
    using System;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;

    [Table("Employee")]
    public partial class Employee
    {
        [Key]
        public Guid UID { get; set; }

        [StringLength(10)]
        public string EMPLOYEEID { get; set; }

        [StringLength(50)]
        public string EMP_NAME { get; set; }

        public int? EMP_POSITNID { get; set; }

        [StringLength(30)]
        public string EMP_POSITN { get; set; }

        public int? EMP_TYPE { get; set; }

        [StringLength(2)]
        public string EMP_SEX { get; set; }

        public int? EMP_EDUID { get; set; }

        [StringLength(20)]
        public string EMP_EDU { get; set; }

        public int? EMP_DEGREEID { get; set; }

        [StringLength(20)]
        public string EMP_DEGREE { get; set; }

        public DateTime? EMP_DBIRTH { get; set; }

        public int? EMP_RANKID { get; set; }

        [StringLength(12)]
        public string EMP_RANK { get; set; }

        public int? EMP_TCLassID { get; set; }

        [StringLength(20)]
        public string EMP_TCLass { get; set; }

        public int? EMP_TRAINID { get; set; }

        [StringLength(40)]
        public string EMP_TRAIN { get; set; }

        [StringLength(50)]
        public string EMP_SCHOOL { get; set; }

        [StringLength(50)]
        public string EMP_NATIVE { get; set; }

        [StringLength(30)]
        public string EMP_Major { get; set; }

        [StringLength(18)]
        public string EMP_WORKID { get; set; }

        [StringLength(50)]
        public string EMP_WSTROY { get; set; }

        public DateTime? EMP_WORKTIME { get; set; }

        [StringLength(20)]
        public string EMP_Phone { get; set; }

        [StringLength(50)]
        public string EMP_Address { get; set; }

        //[Column(TypeName = "image")] // 注释以解决sqlite不支持iamge类型的数据
        public byte[] EMP_PICTUR { get; set; }

        [StringLength(18)]
        public string EMP_IDCAR { get; set; }

        public DateTime? EMP_BWORKTIME { get; set; }

        public DateTime? EMP_EWORKTIME { get; set; }

        public int? GroupID { get; set; }

        [StringLength(15)]
        public string GroupName { get; set; }

        [StringLength(50)]
        public string PassWordStr { get; set; }

        [StringLength(20)]
        public string IDCardStr { get; set; }

        [StringLength(200)]
        public string Emp_DefMenu { get; set; }

        // [Column(TypeName = "image")] // 注释以解决sqlite不支持iamge类型的数据
        public byte[] Emp_Image { get; set; }

        public double? Emp_Weight { get; set; }

        [StringLength(200)]
        public string EMP_Roles { get; set; }

        [StringLength(200)]
        public string EMP_Grant { get; set; }

        [StringLength(50)]
        public string JYW { get; set; }

        [StringLength(50)]
        public string EMP_DriverLevel { get; set; }

        // [Column(TypeName = "image")] // 注释以解决sqlite不支持iamge类型的数据
        public byte[] EMP_SignNameWatermark { get; set; }

        public string ZWTP { get; set; }

        public string ZWTZM { get; set; }

        public string ZWTP2 { get; set; }

        public string ZWTZM2 { get; set; }
    }
}
// Model1 是给EF Sqlserver用的
using System.Data.Entity;

namespace ClassLibrary1.DataAccess
{
    public partial class Model1 : DbContext
    {
        public Model1()
            : base("name=Model1")
        {
        }

        public virtual DbSet<Employee> Employee { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Employee>()
                .Property(e => e.EMPLOYEEID)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_NAME)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_POSITN)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_SEX)
                .IsFixedLength()
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_EDU)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_DEGREE)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_RANK)
                .IsFixedLength()
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_TCLass)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_TRAIN)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_SCHOOL)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_NATIVE)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_Major)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_WORKID)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_WSTROY)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_Phone)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_Address)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_IDCAR)
                .IsFixedLength()
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.GroupName)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.PassWordStr)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.IDCardStr)
                .IsFixedLength()
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.Emp_DefMenu)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_Roles)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_Grant)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.JYW)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_DriverLevel)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.ZWTP)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.ZWTZM)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.ZWTP2)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.ZWTZM2)
                .IsUnicode(false);
        }
    }
}
// Model2 是给EF SQLite用的 
using System.Data.Common;
using System.Data.Entity;
using System.Data.SQLite.EF6;
using System.Windows.Forms;

namespace ClassLibrary1.DataAccess
{
    public partial class Model2 : DbContext
    {
        private static string connStr = $"data source={Application.StartupPath}\\newgajck_adas.db";

        public Model2()
            : base("name=Model2")
        {
        }

        public static Model2 Instance
        {
            get
            {
                DbConnection sqliteCon = SQLiteProviderFactory.Instance.CreateConnection();
                sqliteCon.ConnectionString = connStr;
                return new Model2(sqliteCon);
            }
        }

        private Model2(DbConnection con) : base(con, true)
        {
        }

        public virtual DbSet<Employee> Employee { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Employee>()
                .Property(e => e.EMPLOYEEID)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_NAME)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_POSITN)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_SEX)
                .IsFixedLength()
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_EDU)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_DEGREE)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_RANK)
                .IsFixedLength()
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_TCLass)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_TRAIN)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_SCHOOL)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_NATIVE)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_Major)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_WORKID)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_WSTROY)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_Phone)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_Address)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_IDCAR)
                .IsFixedLength()
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.GroupName)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.PassWordStr)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.IDCardStr)
                .IsFixedLength()
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.Emp_DefMenu)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_Roles)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_Grant)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.JYW)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.EMP_DriverLevel)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.ZWTP)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.ZWTZM)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.ZWTP2)
                .IsUnicode(false);

            modelBuilder.Entity<Employee>()
                .Property(e => e.ZWTZM2)
                .IsUnicode(false);
        }
    }
}
<!-- ClassLibrary1 的App.config 配置文件 -->
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <entityFramework>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
      <!-- 1. Solves SQLite error of "Unable to find the requested .Net Framework Data Provider."-->
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, 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>
  <connectionStrings>
    <add name="Model1" connectionString="data source=.\sqlexpress;initial catalog=NewGajck_adas;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
    <add name="Model2" connectionString="Data Source=D:\\My Work\\SVN Source code\\ECUFlashSystem\\trunk\\StationApp\\bin\\Debug\\newgajck_adas.db" providerName="System.Data.SQLite.EF6" />
  </connectionStrings>
</configuration>
<!-- Form1 的App.config 配置文件 -->
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <entityFramework>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
      <!-- 1. Solves SQLite error of "Unable to find the requested .Net Framework Data Provider."-->
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
  </entityFramework>
  <connectionStrings>
    <add name="Model1" connectionString="data source=.\sqlexpress;initial catalog=NewGajck_adas;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
    <add name="Model2" connectionString="Data Source=D:\\My Work\\SVN Source code\\ECUFlashSystem\\trunk\\StationApp\\bin\\Debug\\newgajck_adas.db" providerName="System.Data.SQLite.EF6" />
  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
  </startup>
</configuration>

2.2 运行项目

    运行 Form1 ,出现错误 System.NotSupportedException: 'Unable to determine the provider name for provider factory of type 'System.Data.SQLite.SQLiteFactory'. Make sure that the ADO.NET provider is installed or registered in the application config.' 如下:
在这里插入图片描述

2.3 解决办法

    将 ClassLibrary1 项目中的 App.config 配置文件的内容复制到 Form1App.config 中,并且需要注意的是 <startup> 节点需要放在 <configSections> 之后,如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <entityFramework>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
      <!-- 1. Solves SQLite error of "Unable to find the requested .Net Framework Data Provider."-->
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
  </entityFramework>
  <connectionStrings>
    <add name="Model1" connectionString="data source=.\sqlexpress;initial catalog=NewGajck_adas;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
    <add name="Model2" connectionString="Data Source=D:\\My Work\\SVN Source code\\ECUFlashSystem\\trunk\\StationApp\\bin\\Debug\\newgajck_adas.db" providerName="System.Data.SQLite.EF6" />
  </connectionStrings>
  <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>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
  </startup>
</configuration>

    再次运行程序,发现报错问题解决了,dataGridView1是用 EFSQLSERVER 中读取出来的数据,dataGridView2是用 EFSQLite 中读取出来的数据,如下:
在这里插入图片描述

2.4 注意事项

    多项目情况下,假如数据库访问代码与主程序不在同一个项目下(如文中ClassLibrary1SQLiteForEF项目),则需要将数据库访问项目App.config 的配置信息放到主程序App.config 中。
    并且需要让主程序App.config<startup> 节点放在 <configSections> 之后,否则就会出现下面的配置文件错误情况,如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值