2017-09-08 48 views
3

我想要完整的连接字符串传递给DbContext构造函数的参数,我得到这个错误:如何通过全SQLite的连接字符串的DbContext

Unable to complete operation. The supplied SqlConnection does not specify an initial catalog or AttachDBFileName.

这是我曾尝试:

public DatabaseContext() :base(@"Data Source=|DataDirectory|ComponentDatabase.sqlite") {} 

问题不能得到其他任何东西,但连接字符串,因为我能够使用连接字符串来连接我的数据库从App.config这样的:

的App.config

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 
    </configSections> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> 
    </startup> 
    <entityFramework> 
    <providers> 
     <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" /> 
     <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" /> 
    </providers> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
     <parameters> 
     <parameter value="mssqllocaldb" /> 
     </parameters> 
    </defaultConnectionFactory> 
    </entityFramework> 
    <connectionStrings> 
    <!-- use AppDomain.SetData to set the DataDirectory --> 
    <add name="MapDbConnectionStr" connectionString="Data Source=|DataDirectory|ComponentDatabase.sqlite" providerName="System.Data.SQLite" /> 
    </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> 
    <runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-1.0.105.2" newVersion="1.0.105.2" /> 
     </dependentAssembly> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Data.SQLite.EF6" publicKeyToken="db937bc2d44ff139" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-1.0.105.2" newVersion="1.0.105.2" /> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 
</configuration> 

的DbContext

public DatabaseContext() :base("MapDbConnectionStr") {} 

附:我知道App.config有很多不必要的行,是的。

+1

不知道重复但这可能有助于https://stackoverflow.com/a/35982626/2946329 –

+0

不,它是关于丢失MSSQL数据库中配置文件中的初始目录,这是关于将实际连接字符串传递给Sqlite中的构造函数。 AFAIK Sqlite没有inital目录选项。即使它有,直接传递给构造函数时仍然无法找到正确的字符串形式。 – ferit

+1

如果你只使用** SQLite数据库,这里是一个不需要任何配置文件的解决方案 - [EF6,SQLite在没有App.confg的情况下无法工作](https://stackoverflow.com/questions/43615926/ef6-sqlite-wont-work-without-app-confg/43688403#43688403) –

回答

2

据我所知,没有连接工厂的数据库类型,你正试图连接到。

你可以编写自己的连接工厂:

public class MySqlLiteConnectionFactory : IDbConnectionFactory 
{ 
    public DbConnection CreateConnection(string connectionString) 
    { 
     return new SQLiteConnection(connectionString); 
    } 
} 

现在去找到的app.config为defaulConnectionfactory的条目,并替代其指定类型的线。目前,多数民众赞成要读这样的事情:

<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 

改变它的东西是这样的:

<defaultConnectionFactory type="MyNamespace.MySQLiteConnectionFactory, MyAssemblyHere" /> 

您现在应该能够正确使用上下文构造函数(字符串的connectionString)。

还有一种做法不依赖于应用程序EF 6,并且支持基于代码的配置。

所以,你可以用配置的东西,看起来有点像这样:这

DbConfiguration.Loaded += (_, a) => 
    { 
     a.ReplaceService<DbProviderServices>((s, k) => new MyProviderServices(s)); 
     a.ReplaceService<IDbConnectionFactory>((s, k) => new MyConnectionFactory(s)); 
    }; 

全部细节记载here at microsoft

+0

谢谢你的回答。有没有办法完全避免取决于app.config?我想传递完整的连接字符串,因为我想避免使用app.config。 – ferit

+0

我想我找到了它,在'DbContext'类中创建了一个'SQLiteConfiguration:DbConfiguration'类,但仍然得到了'无法完成操作。提供的SqlConnection没有指定初始目录或AttachDBFileName.' – ferit

+0

我已经增加了文章,应该通过某种方式来帮助您实现目标。 –

0

使用配置文件中的名称是可行的,因为它可以根据提供的配置确定提供程序类型。在构造函数中直接使用连接字符串时,它无法确定连接字符串是否适用于SQLite,并且假定MSSQL正在尝试使用SqlConnection。因此你遇到的错误信息。

注意:

The connection to the database (including the name of the database) can be specified in several ways. If the parameterless DbContext constructor is called from a derived context, then the name of the derived context is used to find a connection string in the app.config or web.config file. If no connection string is found, then the name is passed to the DefaultConnectionFactory registered on the Database class. The connection factory then uses the context name as the database name in a default connection string. (This default connection string points to .\SQLEXPRESS on the local machine unless a different DefaultConnectionFactory is registered.) Instead of using the derived context name, the connection/database name can also be specified explicitly by passing the name to one of the DbContext constructors that takes a string. The name can also be passed in the form "name=myname", in which case the name must be found in the config file or an exception will be thrown. Note that the connection found in the app.config or web.config file can be a normal database connection string (not a special Entity Framework connection string) in which case the DbContext will use Code First. However, if the connection found in the config file is a special Entity Framework connection string, then the DbContext will use Database/Model First and the model specified in the connection string will be used. An existing or explicitly created DbConnection can also be used instead of the database/connection name.

Taken from the class remarks for DbContext

最后引用的句子中脱颖而出......

An existing or explicitly created DbConnection can also be used instead of the database/connection name.

你可以考虑使用SQLiteConnection

public class DatabaseContext : DbContext { 

    public DatabaseContext() 
     :base(new SQLiteConnection(@"Data Source=|DataDirectory|ComponentDatabase.sqlite"), true) { 
     //... 
    } 

    //... 
} 
+0

那么,我问的是传递完整的连接字符串,而不是传递连接对象。当你传递一个连接对象时,实体框架不能完全控制它,所以将来可能会导致小规模问题。我宁愿避免它。 – ferit

+0

@Saibot你读过引用的文字吗? – Nkosi

+0

是的,但没有帮助。 – ferit

-1

正如我理解正确它可能会有所帮助,请使用数据库上下文选项的生成器。我使用SqlServer,但是应该没有太多变化。

var builder = new DbContextOptionsBuilder<MapDbContext>(); 
builder.UseSqlServer(ConfigurationManager.ConnectionStrings["MapDbConnectionStr"].ConnectionString), opt => opt.EnableRetryOnFailure()); 
var mycontext = new MapDbContext(builder.Options); 

public MapDbContext(DbContextOptions<MapDbContext> options) 
     : base(options) 
    { } 

希望它有帮助,祝你好运。