I need to have DbProviderFactories.GetFactory() return the provider for Sqlite. However, I have Sqlite added to my project via NuGet and want to avoid having to put it in the GAC and update machine.config. One of the advantages of Sqlite is it is there with no configuration.
However, I have a number of libraries that pull the connector from GetFactory().
Is there a way to do this?
thanks - dave
You just have to add an app.config file to your project, with the invariant that you want to add.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite"></remove>
<add name="ADO.NET Provider for SQLite"
invariant="System.Data.SQLite"
description="ADO.NET Provider for SQLite "
type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite">
</add>
</DbProviderFactories>
</system.data>
</configuration>
The type attribute contains the namespace of the provider factory and the namespace of the provider itself.
The GetFactory method first looks in your local app.config file, then in your machine.config. Just make sure that you do have a reference to the SQLite assembly, as you do.
Related
I thought that sqlite was simple but it is giving me a hard time. I just want to create an application where I can connect to a sqlite database using the ado.net entity data classes.
I am having this problem when testing the application on a virtual computer running windows xp. the application works fine on my current computer and also on my laptop when I deploy them.
Here is what happens on the virtual computer :
The application is able to launch.
The application is able to interact with the database using System.Data.SQLite
The application is not able to connect to the database using The ADO.NET Entity data models
when I try to connect I get the following exception:
I know there are a lot of post that talk about this and most of them say that you need to download the .NET provider for Sqlite.
I have already installed the sqlite-netFx40-setup-bundle-x86-2010-1.0.79.0.exe and I get the same problem. What should I do?
Edit
I managed to establish a connection by adding:
<system.data>
<DbProviderFactories>
<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>
to my app.config file.
The problem is that now I cannot select data nor insert records to the database. The exception that I get when I try to insert a new record now is:
A null was returned after calling the 'GetService' method on a store provider instance of type 'System.Data.SQLite.SQLiteFactory'. The store provider might not be functioning correctly.
had to add:
<system.data>
<DbProviderFactories>
<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>
to my app config file. and it now looks like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319" sku=".NETFramework,Version=v4.0,Profile=Client" />
</startup>
<system.data>
<DbProviderFactories>
<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>
</configuration>
In the location where sqlite was installed I had to copy
to my output directory where my program exe is located
Install SQLite Toolbox through extensions
Download the latest setup file sqlite-netFx46-setup-bundle-x86-2015-1.0.xxx.0.exe
Install the correct x86 installation, installing VS designer components is a option in the MSI, there is bold text detailing this underneath the correct installation.
Restart and check SQLite in GAC was installed correctly by clicking the blue question mark above your connected databases underneath SQLite toolbox.
At this point you should see "SQLite EF6 DbProvider in GAC - Yes."
Elsewise, you most likely configured your machine.config manually in the past. Delete the changes you made underneath system.data > DbProviderFactories.
Restart VS and you should see "SQLite EF6 DbProvider in GAC - Yes."
Install System.Data.SQLite under the NuGet manager.
You can now connect to SQLite as a binding source and directly select your database file through "SQLite Database" vs "SQLite Provider (Simple for EF6 by ErikEJ)."
refer to this link, this solution was taken from a detailed github post, step by step
I have a asp.net mvc 5.1 solution with 3 projects in it shown by the image below:
I have Ninject, FakeitEasy, MySql nuget packages installed in my project and I am using the repository pattern in my project so I have an IRepository generic interface, IDbContext interface and a concrete repository generic class (all this is in the AccountManager.Domain).
With everything Ninject and mysql all setup, I built the solution and so far so good until I tried to add a controller using the scaffolding options given with Entity Framework and I get an error saying:
Unable to retrieve metadata for 'AccountManager.Domain.Entities.Bank' using the same DbCompiledModel to create contexts against different types of Database servers is not supported. Instead create a separate DbCompiledModel for each type of server being used.
I saw this when I was head banging with sqlite and EF code first. What does it mean again? Anyone see some perspective I don't?
I have been plugging away at this annoyance for a while and I found that its something that is just simple. Decorating my context class with this mysqlefconfig like so:
[DbConfigurationType(typeof(MySqlEFConfiguration))]
helps the context to make the necessary adjustments to the migration table EF creates automatically so it works with MySql is the reason why my controllers didn't scaffold at all. I got the idea to try comment this out from https://stackoverflow.com/users/3671905/yurko and the scaffolding worked gorgeously.
Only thing to note is that after you finished your scaffolding you need to uncomment it so that all the MySQL peculiarities required by EF should be restored. I prefer attribute configuration than creating files and editing infrastructure files.
Well, for me the only thing that worked was delete everything in the config file(app.config or web.config) and paste the following:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description="Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" />
</DbProviderFactories>
</system.data>
<connectionStrings>
<add name="MyContext" connectionString="server=127.0.0.1; User Id=root; Password=password; Persist Security Info=True; database=Test;" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
</configuration>
Source
After that i've been able to generate the controllers, i hope that it helps.
(And of course, its necessary to configure correctly the connection strings)
Im using Visual Studio 2010 Ultimate, C# WPF, MVVM, Sqlite.
I have this project that is running without problems (On Windows 8 x64, .NET Framework 4 Client Proile), but I get all this exceptions when run an installed application (On Windows 7 x32, .NET Framework 4 Client Proile):
Exception: System.Windows.Markup.XamlParseException: 'The invocation of the constructor of type' GestorDocument.UI.DeterminanteView 'that matches the specified binding constraints threw an exception.' (Line number: '3 ', line position '9'). ---> System.ArgumentException: The specified store provider can not be found in the configuration or is not valid. ---> System.ArgumentException: Could not find the data provider. NET Framework requested. It may not be installed.
This is my connection string:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="GestorDocumentEntities" connectionString="metadata=res://*/GestorDocument.csdl|res://*/GestorDocument.ssdl|res://*/GestorDocument.msl;provider=System.Data.SQLite;provider connection string="data source=C:\SQLITE\BD\GestorDocument.s3db"" providerName="System.Data.EntityClient"/>
</connectionStrings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration>
Please, Any idea?
Now it works!
MY SOLUTION WAS:
App.config in your project:
<configuration>
<system.data>
<DbProviderFactories>
<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, Version=1.0.85.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
</DbProviderFactories>
</system.data>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
</startup>
</configuration>
Include a reference of: (version for the machine on which the application will be installed.)
SQLite.Designer.dll
System.Data.SQLite.dll
System.Data.SQLite.Linq.dll
Set "Copy local" property to True.
Add in machine.config this line between system.data and DbProviderFactories
<add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.85.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
Ensure that the version of. NET Framework, which was developed the application, is installed on the test machine.
The System.Data.SQLite provider isn't installed on the machine. The correct installation not only drops the binaries on the machine (probably the GAC), but also drops an entry into machine.config that looks something like this (this is NOT REAL):
<system.data>
<DbProviderFactories>
<add name="System.Data.SQLite"
invariant="System.Data.SQLite"
description="SQLite Framework Data Provider for SQLite databases lol"
type="SomeProviderFactory, System.Data.SQLite, Etcetera=etcetera"/>
<!--snip-->
</DbProviderFactories>
</system.data>
Configuration settings (like this database provider configuration) in machine.config are inherited by your application's derp.exe.config file. In your .config file, you are configuring EF to use the SQLite provider (from the middle of your EF connection string):
provider=System.Data.SQLite;
If you look up at the hypothetical entry, it has a provider name that's the same as in your connection string. That's how EF knows to use the SQLite factory to create a connection to the database. See, it's not really magic at all. Its just hidden.
So what's the solution? Hell if I know. I mean, I use a REAL compact database, not this SQLite stuff. You will either have to install SQLite on the target machine, add the factory definition to your .config file, or do something else, like construct a plane out of bamboo.
I have an EF 5.0 model that has been generated from the database. This model exists in a class library project. This class library project has an app.config file that contains the connection string information for the model.
Whenever I choose "Update model from database", I have to reenter the connection string. It doesn't seem to see the string from the app.config file.
Also, during the model update, if I click to save the connection string in the app.config, it never does.
Here is my app.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
<connectionStrings>
<add name="mapEntities"
connectionString="metadata=res://*/mapModel.csdl|
res://*/mapModel.ssdl|
res://*/mapModel.msl;
provider=Oracle.DataAccess.Client
provider connection string=
"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=myserver.com)(PORT=1521)))(CONNECT_DATA=(SID=MYDB)));User Id=MYUSERNAME;Password=MYPASSWORD;""
providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
How do I make EF see the connection string from the app.config? I need to add a function import to the model and I can't because it says that no connection has been configured for the model.
EDIT
Well I found a solution, abeit a hacky one.
See this stackoverflow post here.
The OP stated that he recreated a new EDMX file in the project, and that fixed it. I did the same, it did. I did not regenerate my old EDMX file. I just created a new one, and then went back to the old EDMX and it works now.
Copy the connectionString section to your web.config file.
I'm trying to learn and figure out if it is possible to deploy an MVC, EF, ODAC 11.2.0.3 app to a server that has a previous version of ODP.NET installed. Rather than updating the sever ODP.NET (which I can't), I figured I could use the Oracle Instant Client.
Is this doable?
1) I added these dlls to my project to support Instant Client
-Oracle.DataAccess.dll
-oci.dll
-ociw32.dll
-orannzsbb11.dll
-oraociei11.dll
-OraOps11w.dll
2) Next I updated web.config for the dbProviderFactories
<system.data>
<DbProviderFactories>
<add name="Oracle Data Provider for .NET"
invariant="Oracle.DataAccess.Client"
description="Oracle Data Provider for .NET"
type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
3) This (afaik) is how to use the Oracle dll in the bin rathre than the GAC
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Oracle.DataAccess" publicKeyToken="89b483f429c47342" />
<publisherPolicy apply="no" />
</dependentAssembly>
</assemblyBinding>
</runtime>
4) Finally my connectionString
<connectionStrings>
<add name="Entities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=Oracle.DataAccess.Client;
provider connection string="DATA SOURCE=XXX;PASSWORD=XXX;PERSIST SECURITY INFO=True;USER ID=XXX"" providerName="System.Data.EntityClient" />
</connectionStrings>
This is the error I receive
Unable to find the requested .Net Framework Data Provider. It may not be installed.
I really appreciate any help here. I'm rather new and have a lot to learn. Thanks in advance. cheers
Add a <remove … /> section in the <DbProviderFactories> element in the web config to remove any existing Oracle provider. (before the <add>)
<remove invariant ="Oracle.DataAccess.Client" />
It seems from your question that you need to deploy an update to your application and the new version of ODP.net using only xcopy deployment permission.
Since your application is being changed, then you shouldn't need the assembly binding changes or DbProviderFactories.
Just update the csproj of the class library with your edmx etc to have a reference to the new ODP.net version, eg
<Reference Include="Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86" />
If you get an issue with your tnsnames.ora, then you would have to do one of the following:
a) Add a system environment variable TNS_ADMIN to point to the directory of the tnsnames.ora, or
b) Change the connection string to something based on:
Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=MyHost)(PORT=MyPort)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=MyOracleSID)));User Id=myUsername;Password=myPassword;
c) See if you can put a copy of the tnsnames.ora somewhere else.
Here is my Xcopy solution.
I posted it over at
(https://jeremybranham.wordpress.com/2011/04/25/oracle-instant-client-with-odp-net/#comment-181)
as well.
But I think I can post my xml without formatting issues here.
Nuget "packages.config"
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommonServiceLocator" version="1.0" targetFramework="net35" />
<package id="EnterpriseLibrary.Common" version="5.0.505.0" targetFramework="net35" />
<package id="EnterpriseLibrary.Data" version="5.0.505.0" targetFramework="net35" />
<package id="EntLibContrib.Data.OdpNet" version="5.0.505.0" targetFramework="net35" />
<package id="Unity" version="2.1.505.2" targetFramework="net35" />
<package id="Unity.Interception" version="2.1.505.2" targetFramework="net35" />
</packages>
app.config
(note the <clear /> tag below. this may or may not be needed, but I figured it was better to clear them out since you don't know what may be in the machine.config file)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<dataConfiguration defaultDatabase="OracleMainConnectionString">
</dataConfiguration>
<connectionStrings>
<add name="OracleMainConnectionString"
connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=MyOracleServerName)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=MyServiceName)));User ID=MyUserName;Password=MyPassword;"
providerName="Oracle.DataAccess.Client" />
</connectionStrings>
<appSettings>
<add key="ExampleKey" value="ExampleValue" />
</appSettings>
<system.data>
<DbProviderFactories>
<clear />
<add name="Oracle Data Provider for .NET" invariant="Oracle.DataAccess.Client" description=".Net Framework Data Provider for Oracle" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=2.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
<add name="EntLibContrib.Data.OdpNet" invariant="EntLibContrib.Data.OdpNet" description="EntLibContrib Data OdpNet Provider" type="EntLibContrib.Data.OdpNet.OracleDatabase, EntLibContrib.Data.OdpNet, Version=5.0.505.0, Culture=neutral, PublicKeyToken=null" />
</DbProviderFactories>
</system.data>
</configuration>
I am developing on a x64 Windows 7 machine.
I downloaded:
ODAC1120320Xcopy_32bit.zip
(from oracle.com)
Which is the:
ODAC 11.2 Release 5 (11.2.0.3.20) Download the XCopy version [Released September 11, 2012]
I unzipped this zip file.
I searched and fished out these files:
oci.dll
Oracle.DataAccess.dll
orannzsbb11.dll
oraociei11.dll
OraOps11w.dll
Note, when there were 2 files of the same name, I took the "bin\2.x\" or "odp.net20\bin" version for my 3.5 Framework need (I'm not on 4.0 yet).
I took these files, and put them in a subfolder from where my .sln file resides.
.\MySolution.sln
.\MyConsoleApplicationFolder\MyConsoleApp.csproj
.\ThirdPartyReferences\
.\ThirdPartyReferences\Oracle\
I place all the files above in the
.\ThirdPartyReferences\Oracle\
folder
I used "Add Reference" to add a reference to Oracle.DataAccess.dll to the "MyConsoleApp.csproj" csharp project.
(This meant browsing to "..\ThirdPartyReferences\Oracle\" of course)
I used a "Post Build Event" to copy the "extra" (aka, "accessory)" files
My lines in my post build event were:
copy $(ProjectDir)..\ThirdPartyReferences\Oracle\oci.dll $(TargetDir)*.*
copy $(ProjectDir)..\ThirdPartyReferences\Oracle\orannzsbb11.dll $(TargetDir)*.*
copy $(ProjectDir)..\ThirdPartyReferences\Oracle\oraociei11.dll $(TargetDir)*.*
copy $(ProjectDir)..\ThirdPartyReferences\Oracle\OraOps11w.dll $(TargetDir)*.*
Note, my post build event replaces the "Copy if Newer" from the URL instructions above.
When I ran my project........I got a few missing dll errors.
Note:
In the assembly that has your calls to the EnterpriseLibrary.Data objects…you’ll get “Cannot find Microsoft.Practices.SomethingSomething namespace. Just keep adding references to these dll’s (that the above package.config will pull down) until the errors go away.
Like here is a specific one:
"Could not load file or assembly 'Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified."
So (after running Nuget of course, to download all the files)
I went and added a reference to:
\packages\CommonServiceLocator.1.0\lib\NET35\Microsoft.Practices.ServiceLocation.dll
That cleared up the issues.
And my csharp code: (note "select *" is for demo purposes only)
/*
using System;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
*/
public IDataReader EmployeesGetAll()
{
IDataReader returnReader = null;
try
{
Database db = DatabaseFactory.CreateDatabase();
DbCommand dbc = db.GetSqlStringCommand("SELECT * FROM ( SELECT * FROM TEMPLOYEE ) WHERE ROWNUM <= 25");
returnReader = db.ExecuteReader(dbc);
return returnReader;
}
finally
{
}
}
And it worked.
Thank you:
https://jeremybranham.wordpress.com/2011/04/25/oracle-instant-client-with-odp-net/#comment-181
I think this makes ODP.NET an "xcopy" deployment.
I still need to test on a clean machine to be sure.
But its the end of the day..............
================
Additional Information:
Everything above is correct. However, I hit a caveat.
I was using a "Console Application" to test my code.
When you add a new Console Application to visual studio, it DEFAULTS to x86.
As seen here:
http://www.xavierdecoster.com/post/2011/02/15/console-application-visual-studio-gotcha-on-x64-os-aspx
EDIT: (Updated link)
http://www.xavierdecoster.com/post/2011/02/15/console-application-visual-studio-gotcha-on-x64-os
So when I put all the configuration and code and stuff in a real project (which was set to "Any CPU" on a x64 bit machine)...everything I had done stopped working. :<
After tweaking a bit........
I found this file on oracle.com
ODAC1120320Xcopy_x64.zip
I then repeated everything I did above , but searching the unzipped files of this x64 zip file.
Everything is working.
But that "x86" default thing with a Console application threw me for a loop.
I was getting the same error (data provider not found) when deploying ODP.NET via Instant Client. The only thing that I needed to do was to add the following to my exe.config file (inside the tag)
<system.data>
<DbProviderFactories>
<add name="Oracle Data Provider for .NET"
invariant="Oracle.DataAccess.Client"
description="Oracle Data Provider for .NET"
type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>