本文介绍了SQLite EF6在运行时以编程方式设置连接字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试将EF 3.5迁移到6(以SQLite为数据库)。我们无法在应用配置文件中设置连接字符串(这在ef6中没有问题)。我们必须在运行时(在用户选择了SQLite文件之后)以编程方式设置连接字符串。



这是我们的app.config

 <?xml version =1.0encoding =utf-8?> 
< configuration>
< configSections>
<! - 有关实体框架配置的更多信息,请访问http://go.microsoft.com/fwlink/?LinkID=237468 - >
< section name =entityFrameworktype =System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,EntityFramework,Version = 6.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089requirePermission =false/> ;
< / configSections>
< connectionStrings>
< add name =testContextconnectionString =data source = Data\testdb.sqlite; Foreign Keys = True
providerName =System.Data.SQLite/>
< / connectionStrings>
< entityFramework>
< defaultConnectionFactory type =System.Data.Entity.Infrastructure.LocalDbConnectionFactory,EntityFramework>
< parameters>
< parameter value =v11.0/>
< / parameters>
< / defaultConnectionFactory>
< providers>
< provider invariantName =System.Data.SQLitetype =System.Data.SQLite.EF6.SQLiteProviderServices,System.Data.SQLite.EF6/>
< / providers>
< / entityFramework>
< system.data>
< DbProviderFactories>
< remove invariant =System.Data.SQLite/>
< remove invariant =System.Data.SQLite.EF6/>
< add name =System.Data.SQLiteinvariant =System.Data.SQLitedescription =。SQLite(实体框架6)的Net Framework数据提供程序type =System.Data.SQLite。 EF6.SQLiteProviderFactory,System.Data.SQLite.EF6/>
< / DbProviderFactories>
< /system.data>
< / configuration>

这里是DbContext

  public class FirmwareContext:DbContext 
{
public FirmwareContext()
:this(DEFAULT_CONNECTION)
{

}

public FirmwareContext(string connextionNameOrString)
:base(connextionNameOrString)
{

}
}

如果我使用app.config中的连接名称连接所有的工作没有问题。如果我尝试传递与第二个构造函数的连接字符串,这将失败



这里是一个小例子

  SQLiteConnectionStringBuilder builder = 
factory.CreateConnectionStringBuilder()as SQLiteConnectionStringBuilder;
builder.DataSource = dataSource; //用户名的路径
builder.ForeignKeys = true;

var context = new FirmwareContext(builder.ToString());

var context = new FirmwareContext(builder.ToString());
var test = context.Firmware.FirstOrDefault();

我有以下异常(Schlüsselwortwird nichtunterstützt:'foreign keys'。)=>关键的外键不支持。如果我删除外键集,我得到以下异常(提供者没有返回ProviderManifestToken字符串)和一些内部异常。



似乎bas(connectionString)构建MSSQL连接字符串和SQLite。



如何使我的第二个构造函数与sqlite相容?

解决方案

我有同样的问题。通过使用基类DbContext类中的不同构造函数,我发现了一种解决方法:

  public DbContext(DbConnection existingConnection,bool contextOwnsConnection); 

使用此覆盖可以传递一个SQLiteConnection,而不是设置连接字符串。所以例如你可以添加一个新的构造函数到FirmwareContext。

  public FirmwareContext(string connectionString)
:base新的SQLiteConnection(){ConnectionString = connectionString},true)
{
}

甚至

  public FirmwareContext(string filename)
:base(new SQLiteConnection(){ConnectionString =
new SQLiteConnectionStringBuilder()
{DataSource = filename,ForeignKeys = true}
.ConnectionString},true)
{
}
/ pre>

I try to migrate form EF 3.5 to 6 (with SQLite as database). We can not set the connection string in the app config file (this works without problems with ef6). We have to set connection string programmatically at runtime (after user has selected the SQLite file).

Here is our 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>
  <connectionStrings>
    <add name="testContext" connectionString="data source=Data\testdb.sqlite;Foreign Keys=True"
      providerName="System.Data.SQLite" />
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <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" />
      <remove invariant="System.Data.SQLite.EF6" />
      <add name="System.Data.SQLite" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
    </DbProviderFactories>
  </system.data>
</configuration>

Here ist the DbContext

public class FirmwareContext : DbContext
{
    public FirmwareContext()
        : this(DEFAULT_CONNECTION)
    {

    }

    public FirmwareContext(string connextionNameOrString)
        : base(connextionNameOrString)
    {

    }
}

If I connect with the connecation name from app.config all works without problems. If I try to pass the connection string with the second constructor this fails

Here is small example

SQLiteConnectionStringBuilder builder =
    factory.CreateConnectionStringBuilder() as SQLiteConnectionStringBuilder;
builder.DataSource = dataSource; // Path to file name of the user
builder.ForeignKeys = true;

var context = new FirmwareContext(builder.ToString());

var context = new FirmwareContext(builder.ToString());
var test = context.Firmware.FirstOrDefault();

I got the following exception ("Schlüsselwort wird nicht unterstützt: 'foreign keys'.") => The key 'foreign key' is nott supported. If I remove the foreign key set, I got the following exception ("The provider did not return a ProviderManifestToken string.") and some inner exceptions.

It seems that the bas(connectionString) build the MSSQL connection string and for SQLite.

How can I make my second constructor campatible with sqlite?

解决方案

I was having the same problem. I found a workaround by using a different constructor from the base DbContext class:

public DbContext(DbConnection existingConnection, bool contextOwnsConnection);

Using this override you can pass an SQLiteConnection instead which you set the connection string on. So for example you can add a new constructor to your FirmwareContext.

public FirmwareContext(string connectionString)
    : base(new SQLiteConnection() { ConnectionString = connectionString }, true)
{
}

Or even

public FirmwareContext(string filename)
    : base(new SQLiteConnection() { ConnectionString =
            new SQLiteConnectionStringBuilder()
                { DataSource = filename, ForeignKeys = true }
            .ConnectionString }, true)
{
}

这篇关于SQLite EF6在运行时以编程方式设置连接字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 05:31