Database Connectivity ASP.NET - PostgreSQL - asp.net

Am trying to run a C# application which fetches data from PostgreSQL database(8.4) and am using the PostgreSQL OLE DB Provider
This is my connection string
string connString =
#"Provider=PostgreSQL OLE DB
Provider;Data
Source=localhost;location=;User
ID=;password=;timeout=1000";
The error am getting is
The 'PostgreSQL OLE DB Provider'
provider is not registered on the
local machine
Can anyone point out me where should I correct so as to get the connect to the database. By the way am using PGOLEDBLib.

I have seen a few different "pgoledb" libraries. None appear to actually be named "pgoledblib", so this info may or may not apply to you.
The most recently active PGOLEDB has documented their connection string attributes here; it appears they use a different Provider value -- "PGNP.1".
Another provider, which seems to have been languishing since 2006, has connection strings here; these are in line with the earlier suggestions from OrbMan.
Of course, you may find that paying nothing for such a provider leads to paying much in installation, configuration, and utilization headaches. Towards easing such headaches, I offer a link to my employer's options supporting ODBC, JDBC, and ADO.NET clients on many platforms.

Any particular reason you're using the OLE DB provider? I believe the general idea is that you get better performance, and I think also functionality, if you use a native .net provider - e.g. http://npgsql.projects.postgresql.org/

Try using "PostgreSQL" or "PostgreSQL.1" for the Provider attribute.. If that does not work, you will probably need to re-install the driver.

I found the solution.
Step 1: Down load & install
https://www.pgoledb.com/index.php/component/filecabinet/?task=download&cid[0]=15
Step 2: Restart PC.
Step 3: Set the connection string as below
Provider=PGNP.1;Data Source=localhost;Persist Security Info=True;Initial Catalog=myDatabase;User ID=yyy;password=xxx
It should work as your expected

Related

EntityException: The underlying provider failed on Open. Can one server closing a db connection, make another server fail on opening?

I am experiencing database connection errors with an ASP.NET application written in VB, running on three IIS servers. The underlying database is MS Access, which is on a shared network device. It uses Entity Framework, code first implementation and JetEntityFrameworkProvider.
The application is running stable. But, approximately 1 out of 1000 attempts to open the database connection fails with either one of the following two errors:
06:33:50 DbContext "Failed to open connection at 2/12/2020 6:33:50 AM +00:00 with error:
Cannot open database ''. It may not be a database that your application recognizes, or the file may be corrupt.
Or
14:04:39 DbContext "Failed to open connection at 2/13/2020 2:04:39 PM +00:00 with error:
Could not use ''; file already in use.
One second later, with refreshing (F5), the error is gone and it works again.
Details about the environment and used code.
Connection String
<add name="DbContext" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=x:\thedatabase.mdb;Jet OLEDB:Database Password=xx;OLE DB Services=-4;" providerName="JetEntityFrameworkProvider" />
DbContext management
The application uses public property to access DbContext. DbContext is kept in the HttpContext.Current.Items collection for the lifetime of the request, and is disposed at it’s end.
Public Shared ReadOnly Property Instance() As DbContext
Get
SyncLock obj
If Not HttpContext.Current.Items.Contains("DbContext") Then
HttpContext.Current.Items.Item("DbContext") = New DbContext()
End If
Return HttpContext.Current.Items.Item("DbContext")
End SyncLock
End Get
End Property
BasePage inits and disposes the DbContext.
Protected Overrides Sub OnInit(e As EventArgs)
MyBase.OnInit(e)
DbContext = Data.DbContext.Instance
...
End Sub
Protected Overrides Sub OnUnload(e As EventArgs)
MyBase.OnUnload(e)
If DbContext IsNot Nothing Then DbContext.Dispose()
End Sub
What I have tried
Many of the questions on SO which address above error messages, deal with generally not being able to establish a connection to the database – they can’t connect at all. That’s different with this case. Connection works 99,99% of the time.
Besides that, I have checked:
Permissions: Full access is granted for share where .mdb (database) and .ldb (locking file) resides.
Network connection: there are no connection issues to the shared device; it’s a Gigabit LAN connection
Maximum number of 255 concurrent connections is not reached
Maximum size of database not exceeded (db has only 5 MB)
Changed the compile option from “Any CPU” to “x86” as suggested in this MS Dev-Net post
Quote: I was getting the same "Cannot open database ''" error, but completely randomly (it seemed). The MDB file was less than 1Mb, so no issue with a 2Gb limit as mentioned a lot with this error.
It worked 100% on 32 bit versions of windows, but I discovered that the issues were on 64 bit installations.
The app was being compiled as "Any CPU".
I changed the compile option from "Any CPU" to "x86" and the problem has disappeared.
Nothing helped so far.
To gather more information, I attached an Nlog logger to the DbContext which writes all database actions and queries to a log file.
Shared Log As Logger = LogManager.GetLogger("DbContext")
Me.Database.Log = Sub(s) Log.Debug(s)
Investigating the logs I figured out that when one of the above errors occured on one server, another one of the servers (3 in total) has closed the db connection at exactly the same time.
Here two examples which correspond to the above errors:
06:33:50 DbContext "Closed connection at 2/12/2020 6:33:50 AM +00:00
14:04:39 DbContext "Closed connection at 2/13/2020 2:04:39 PM +00:00
Assumption
When all connections of a DbContext have been closed, the according record is removed from the .ldb lock file. When a connection to the db is being opened, a record will be added to the lock file. When these two events occur at the exact same time, from two different servers, there is a write conflict to the .ldb lock file, which results in on of the errors from above.
Question
Can anyone confirm or prove this wrong? Has anyone experienced this behaviour? Maybe I am missing something else. I’d appreciate your input and experience on this.
If my assumption is true, a solution could be to use a helper class for accessing db, which catches and handles this error, waiting for a minimal time period and trying again.
But this feels kind of wrong. So I am also open to suggestions for a “proper” solution.
EDIT: The "proper" solution would be using a DBMS Server (as stated in the comments below). I'm aware of this. For now, I have to deal with this design mistake without being responsible for it. Also, I can't change it in the short run.
I write this as an aswer because of space but this is not really an answer.
It's for sure an OleDb provider issue.
I think that is a sharing issue.
You could do some tries:
use a newer OleDb provider instead of Microsoft.Jet.OLEDB.4.0. (if you have try 64 bits you could already have try another provider because Jet.OLEDB.4.0 is 32 bits only)
Implement a retry mechanism on the new DbContext()
Reading your tests this is probaly not your case. I THINK that Dispose does not always work properly on Jet.OLEDB.4.0 connections. I noted it on tests and I solved it using a different testing engine. Before giving up I used this piece of code
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
As you can understand reading this code, they are tries and the latest solution was changing the testing engine.
If your app is not too busy you could try to lock the db using a different mechanism (for example using a lock file). This is not really different from new DbContext() retries.
In late '90s I remember I had an issue related to disk sharing OS (I were using Novel Netware). Actually I have not experience in using mdb files on a network share. You could try to move the mdb on a folder shared with Windows
Actually I use Access databases only for tests. If you really need to use a single file database you could try other solutions: SQL Lite (you need a library, also this written by me, to apply code first https://www.nuget.org/packages/System.Data.SQLite.EF6.Migrations/ ) or SQL Server CE
Use a DBMS Server. This is for sure the best solution. As the writer of JetEntityFrameworkProvider I think that single file databases are great for single user apps (for this apps I suggest SQL Lite), for tests (I think that for tests JetEntityFrameworkProvider is great), for transfering data or, also, for readonly applications. In other cases use a DBMS Server. As you know, with EF, you can change from JetEntityFrameworkProvider to SQL Server or to MySql without effort.
You went wrong at the design stage: The MS Access database engine is unfit for ASP.Net sites, and this is explicitly stated on multiple places, e.g. the official download page under details.
The Access Database Engine 2016 Redistributable is not intended .... To be used by ... a program called from server-side web application such as ASP.NET
If you really have to work with an Access database, you can run a helper class that retries in case of common errors. But I don't recommend it.
The proper solution here is using a different RDBMS which exhibits stateless behavior. I recommend SQL Server Express, which has limitations, but if you exceed those you will be far beyond what Access supports, and wont cause errors like this.

Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)

I have a problem when trying to connect to MySQL database using Windows OBDC driver. There are plenty of search hits regarding the obvious... people are using old versions, however, I'm not.
mysqld is on CentOS 6.4 32bit
./usr/libexec/mysqld Ver 5.1.69 for redhat-linux-gnu on i386 (Source distribution)
So I'm at a loss to understand where any pre 4.1.1 protocol is coming from. Any ideas?
I guess that if you ask the right question its easier to find the answer.
In this case "my" problem relates to how the passwords are hashed and stored in the database. Legacy passwords were stored with a shorter hash that's now deprecated.
A few important points:
mysql_upgrade cannot and does not upgrade passwords, nor does it warn about it in some versions, see: http://bugs.mysql.com/bug.php?id=65461.
Even it you have mostly the latest server and clients, all it takes is one legacy client somewhere to create a legacy password and then you'll have trouble with that account no matter what client tries to use it.
Different versions have treated the situation differently so you can be sitting on some legacy passwords in your database and then suddenly, for no apparent reason, some accounts stop working... this is because of how different versions chose to handle the situation.
You cannot upgrade passwords. You must know what they are and you must change them.
EDIT: To be more clear, you must change the password that is stored with the shorter hash using a new client that uses longer hashes. By doing so you will be writing that accounts password with the longer hash, at which point nothing should be flagging attempts to access the account any more. If the problem is recurrent you should be looking for the older clients at your site which are still writing passwords with the deprecated hash length.
MySQL Workbench 6.08 in the Manage Server Connections, Connection tab, Advanced sub-tab you must check the box 'Use the old authentication protocol.'
Try installing old version driver 3.51.30: http://dev.mysql.com/downloads/connector/odbc/5.1.html#downloads
It works on my Mysql Ver 5.0.24a-community
I ran into this while using the ODBC Connector for Windows to connect to a Percona 5.5 server. which has secure_auth disabled.
From what I found the ODBC connector, unlike MySql Workbench, does not support an option to authenticate logins which use the old 16-byte hashed passwords. There is a bug report regarding this, but it appears the assignee is/was confused about the feature request (See bug #71234).
I was able to update the mysql login to use the new 41-byte hash using these commands:
set old_passwords=0;
set password=password('yourpasswordhere');
As I mentioned our server has secure_auth disabled, which appears to cause password() to return old_password() results. Running set old_passwords=0; will enable the password() method to generate the new 41-byte hashes (for the duration of your session).
I had a similar error message when remotely trying to access my MySQL database. Using Directadmin I easily changed the MySql database password as suggested above. This automatically generated the password using the newer hash method. This solved the remote connection problem instantly.
I found another solution in case anyone hits this - very weird -
Install the 5.1 64 bit ODBC driver - verify an ODBC connection by itself works, if you can connect then you should be able to after doing #2
Click on Linked Servers - Providers - right click on MSDASQL, click on Properties
uncheck "Allow inprocess" - which is a good thing to do unless you need to insert TEXT and NTEXT fields.
Create your linked server connection or test the one you have been fighting with - lol
When I had "Allow inprocess" checked I still got the error even though the ODBC system DSN worked fine. I'm assuming because I had a mixture of 5.2 (with servers that worked fine) and 5.1 for the servers that didn't, SQL was sharing the processes because the 5.1 driver does not give that error.
If you can't change your server, perhaps you can change your client: http://bugs.mysql.com/bug.php?id=75425

Connecting to oracle 11g on Red hat linux from windows server using asp.net

We have our application developed and tested with sql server 2008r2 using ASP.NET on windows server. Now we have a requirement to move the database from windows to oracle on red hat linux.
We haven't yet setup the infrastructure to test the same. I would like to know in the meantime if anyone has successfully done this kind of thing. Pointers to any resources will be a great advantage.
Is changing the connection string the only thing that needs to be done or are there any specific configuration in Linux to allow this?
I will verify this once I get the environment ready, but as a headstart if anyone has any similar experience, do share.
Thanks in advance.
P.S: For migration of table structure, storedprocedures etc to oracle we will be using the Sql Developer tool.
I would like to answer my question,because, migration to oracle is not that straight forward, but there are some tips that may help anyone migrate to oracle on windows or linux with less headache.
The first thing the Sql developer tool does a good job of migrating sqlserver schema and data to oracle including storedprocedures, constraints, triggers etc.
It also does a good job of datatype mapping and provides option to remap datatype if required.
Some caveats and precautions.
Oracle has a limitation on the length of stored procedure names of about 30 characters. This is the area you need to resort to some manual renaming as when migration SP's or identifiers whose name is greater than 30 characters may get truncated.
The other common issue that you may face is respect to date insertion and formatting. You can use the following snippet to avoid the headache. The common error will be "Not a valid month."
OracleConnection conn = new OracleConnection(oradb); // C#
conn.Open();
OracleGlobalization session = conn.GetSessionInfo();
session.DateFormat = "DD.MM.RR"; // change the format as required here
conn.SetSessionInfo(session);
The most annoying error would be well character to numeric conversion when inserting or updating data or related error.
The issue here is when you add parameters to command object for sql provider, the binding happens by name, but forOracle.DataAccess the default binding is by position. Here's the post that saved me lot of headache.
ODP .NET Parameter problem with uint datatype
What you can do is set the command.BindByName = true;
When migrating SP's that returns data, oracle creates an out parameter ref cursor. This needs to be taken care of while constructing command parameters.
For e.g.
OracleParameter refp = new Oracle.DataAccess.Client.OracleParameter("cv_1", OracleDbType.RefCursor, ParameterDirection.InputOutput);
command.Parameters.Add(refp);
Also the sqlserver requires parameters to SP be prefixed with "#" and oracle doesn't. This can be easily taken care of in your data layer.
Also since there is no bit datatype in Oracle, number(1) works fine. You may need to convert your bool to numeric, if required.
Hope this helps someone avoid a migration headaches. I will post more issues if I encounter.

what's the issue with AttachDbFilename

Apparently, using AttachDbFilename and user instance in your connection string is a bad way to connect to a DB. I'm using SQL server express on my local machine and it all seems to work fine. But what's the proper way to connect to SQL server then?
Thanks for your explanation.
Using User Instance means that SQL Server is creating a special copy of that database file for use by your program. If you have two different programs using that same connection string, they get two entirely different copies of the database. This leads to a lot of confusion, as people will test updating data with their program, then connect to a different copy of their database in Management Studio, and complain that their update isn't working. This sends them through a flawed series of wild goose chase steps trying to troubleshoot the wrong problem.
This article goes into more depth about how to use this feature, but heed the very first note: the User Instance feature has been deprecated. In SQL Server 2012, the preferred alternatives are (in this order, IMHO):
Create or attach your database to a real instance of SQL Server. Your connection string will then just need to specify the instance name, the database name, and credentials. There will be no mixup as Management Studio, Visual Studio and your program(s) will all be connecting to a single copy of the database.
Use a container for local development. Here's a great starter video by Anna Hoffman and Anthony Nocentino, and I have some other resources here, here, and here. If you're on an M1 Mac, you won't be able to use a full-blown SQL Server instance, but you can use Azure SQL Edge if you can get by with most SQL Server functionality (the omissions are enumerated here).
Use SqlLocalDb for local development. I believe I pointed you to this article yesterday: "Getting Started with SQL Server 2012 Express LocalDB."
Use SQL Server Compact. I like this option the least because the functionality and syntax is not the same - so it's not necessarily going to provide you with all the functionality you're ultimately going to want to deploy. Compact Edition is also deprecated, so there's that.
Of course if you are using a version < SQL Server 2012, SqlLocalDb is not an option - so you should be creating a real database and using that consistently. I only mention the Compact option for completeness - I think that can be almost as bad an idea as using AttachDbFileName.
EDIT: I've blogged about this here:
Bad Habits : Using AttachDBFileName
In case someone had the problem.
When attaching the database with a connection string containing AttachDBFile
with SQLEXPRESS, I noticed this connection was exclusive to the ASP.NET application that was using the database. The connection did block the access to all other processes on the file level when made with System.Data.SqlClient as provider.
In order to assure the connection to be shareable with other processes
instead use DataBase to specify the database name in your connection string
Example or connection string :
Data Source=.\SQLEXPRESS;DataBase=PlaCliGen;User ID=XXX;password=ZZZ; Connect Timeout=30
,where PlaCliGen is the name (or logical name) by which SQLEXPRESS server knows the database.
By connecting to the data base with AttachDBFile giving the path to the .mdf file
(namely : replacing DataBase = PlacliGen by AttachDBFile = c:\vs\placligen\app_data\placligen.mdf) the File was connected exclusively and no other process could connect to the database.

My SQL Server Express has gone nuts it seems, at times mounting db and others not

I am not sure what's going on exactly as I can't establish a strict linear correlation between
events. But below you'll find my connection string, at times it works, other times when I open the app/project I am building (no changes made) it doesn't and gives me various errors and reasons.
<add name="EFDbContext"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA\EFDbContext.mdf;MultipleActiveResultSets=true;Integrated Security=True;User Instance=True"
providerName="System.Data.SqlClient" />
Errors include:
Unable to complete operation. The supplied SqlConnection does not specify an initial catalog.
or
saying Amin-PC\Admin has no access rights (I am logged in admin)
Also when I try to add a new connection at times it will tell me I have no access rights or database already exists or just adds it normally!
I tried explicitly starting visual studio as administrator and this seemed to help with the denied access to the db issue.
Basically I don't know what the heck's going on.
Have recently started with .net and it has been easy coding for asp.net mvc framework until I got to interacting with underlying asp.net infrastructure, connection strings, outdated (noon-entity framework ready) membership provider etc.
And now don't know what's going on with the SQL Server Express edition that gets installed a long with VS2010.
My recommendation would be: since you already have a server instance (.\SQLEXPRESS) installed - attach your databases to the SQL Server Express instance, and then use them under their database name (instead of using the shaky AttachDbFileName= method).
So:
launch your SQL Server Management Studio Express
find your MDF files you want
use Server > Attach Database to attach the MDF/LDF to the server - give it meaningful name
from that point on - use the database on the server and don't attach MDF's on the fly....
Your connection string would then look something like:
server=.\SQLEXPRESS;Database=YourEFDatabaseName;Integrated Security=True
I find this method is typically much more reliable and predictable - the AttachdbFileName= and User Instance=true are supposed to be easier, but tend to be more confusing that anything else....
Refer to SQL Server connection string samples here.

Resources