Querying postgres from c# using npgsql - c#

I have installed postgres in my windows machine and started working on a POC. I am able to connect to the database from the windows command line. But, I am unable to connect from the C# application.
It seems i have some issues in the connection string. I have gone through multiple tutorials but every tutorial has their own way of providing the connection string parameters.Is there any standard way of giving the hostname,port,username,password and database.
I am trying to query using a rest api. Am, I doing the right way.
// GET api/values
[HttpGet]
public IActionResult Get()
{
Test test = new Test();
return Ok(test.Table2Json());
}
using Npgsql;
using System;
namespace Zeiss.MCCNeo.DataMigration.Utilities
{
public class Test
{
private readonly NpgsqlConnection conn;
public Test()
{
conn = new NpgsqlConnection("Server=127.0.0.1;User Id=postgres;" +
"Password=postgres;Database=postgres;");
//also tried using this
conn = new NpgsqlConnection("Server=127.0.0.1;Port=5432;User
Id=postgres;" +
"Password=postgres;Database=postgres;");
}
public string Table2Json()
{
string value = null;
NpgsqlCommand command = new NpgsqlCommand("select * from test",
conn);
NpgsqlDataReader dr = command.ExecuteReader();
while (dr.Read())
{
value = dr[0].ToString();
}
return value;
}
}
}
Exception:
- $exception {System.InvalidOperationException: Connection is not open
at Npgsql.NpgsqlConnection.CheckReadyAndGetConnector()
at Npgsql.NpgsqlCommand.<ExecuteDbDataReader>d__92.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at Npgsql.NpgsqlCommand.ExecuteReader()
at Zeiss.MCCNeo.DataMigration.Utilities.Test.Table2Json() in c:\users\inpyadav\documents\visual studio 2017\Projects\DataMigration\Zeiss.MCCNeo.DataMigration.Utilities\Test.cs:line 19
at DataMigration.Controllers.ValuesController.Get() in c:\users\inpyadav\documents\visual studio 2017\Projects\DataMigration\DataMigration\Controllers\ValuesController.cs:line 18
at lambda_method(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext()} System.InvalidOperationException

Why don't you open connection as it says in error message?
conn.Open();

Related

Exception is thrown while reading the SQL Server Trace

I am trying to capture the queries via SQL Server trace using C# that are getting executed during my automation test run. When I run the below code ,I am getting the exception
'Failed to initialize object as reader.'
So In this case what can be done?
Source Code
class Program
{
static void Main(string[] args)
{
using (Impersonation user = new Impersonation("xxx", "xxx","xxx"))
{
ConnectionInfoBase conninfo = new SqlConnectionInfo();
((SqlConnectionInfo)conninfo).ServerName = "xxxxx";
((SqlConnectionInfo)conninfo).UseIntegratedSecurity = true;
TraceServer trace = new TraceServer();
trace.InitializeAsReader(conninfo, #"Standard.tdf");
for (int count = 0; count < 30; count++)
{
while (trace.Read())
{
Console.WriteLine(trace["TextData"]);
}
Thread.Sleep(1000);
}
}
}
}
Inner Exception
SqlTraceException: Failed to get SQL Tools directory path from InstAPI....
This exception was originally thrown at this call stack:
Microsoft.SqlServer.Management.Trace.TraceUtils.GetSqlToolsBinaryPath(string)
Microsoft.SqlServer.Management.Trace.TraceUtils.CreateInstance(string, string)
Microsoft.SqlServer.Management.Trace.TraceServer.InitializeAsReader(Microsoft.SqlServer.Management.Common.ConnectionInfoBase, string)

MySql.Data.MySqlClient.MySqlException (0x80004005): SELECT command denied to user 'XXX'#'YYY' for table 'bogus_table'

I'm using Dapper for calling MySql stored procedure. The procedure executes just fine, but after that the code throws an exception. The code block that is problematic is like this:
using (var conn = DataFactory.InitializeConnection(false))
{
conn.Query("ProcedureName", new
{
puserid = ID
}, commandType: System.Data.CommandType.StoredProcedure);
}
Where DataFactory is the following static class:
public static class DataFactory
{
public static IDbConnection InitializeConnection(bool open = true, string connectionstring = "", string databaseServerType = "MYSQL")
{
if (string.Equals(databaseServerType, "MYSQL"))
{
if (string.IsNullOrEmpty(connectionstring))
connectionstring = Settings.Default.DataConnectionString;
var csb = new MySql.Data.MySqlClient.MySqlConnectionStringBuilder(connectionstring);
var conn = new MySql.Data.MySqlClient.MySqlConnection(csb.ConnectionString);
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
if (open)
conn.Open();
return conn;
}
throw new NotImplementedException("Not implemented for your database provider");
}
}
I have no bogus_table in my database, tho it is shown in the error message:
MySql.Data.MySqlClient.MySqlException (0x80004005): SELECT command
denied to user 'XXX'#'YYY' for table 'bogus_table' at
MySql.Data.MySqlClient.MySqlStream.ReadPacket() at
MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow,
Int64& insertedId) at
MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean
force) at MySql.Data.MySqlClient.MySqlDataReader.NextResult() at
MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior
behavior) at MySql.Data.MySqlClient.MySqlDataReader.ClearKillFlag()
at MySql.Data.MySqlClient.MySqlDataReader.Close() at
MySql.Data.MySqlClient.MySqlDataReader.Dispose(Boolean disposing)
at MySql.Data.MySqlClient.MySqlDataReader.Dispose() at
Dapper.SqlMapper.d__1361.<>m__Finally1() at
Dapper.SqlMapper.<QueryImpl>d__1361.MoveNext()
it's maybe problem in Mysql Driver implementation; here is code block that mentions bogus_table.
if your procedure has empty result try to call with Execute (because it implements execute non query inside) instead of Query.
using (var conn = DataFactory.InitializeConnection(false))
{
conn.Execute("ProcedureName", new
{
puserid = ID
}, commandType: System.Data.CommandType.StoredProcedure);
}
I encountered, kind of like same issue with 'bogus_table' which indeed comes from MySql code!
MySql.Data.MySqlClient.MySqlException: 'Table 'myspector.bogus_table' doesn't exist'
You are maybe in debug mode with all exceptions enabled.
When this exception raises, uncheck 'break when this exception is thrown' like in the image below:
Then, restart / continue, and you will see that this exception and is catched by another exception handler in the stack : it is transformed into a classic InvalidOperationException:
{"Sequence contains no elements"} System.Exception {System.InvalidOperationException}

MySqlCommand.ExecuteReader() is throwing a System.Format exception on Initialization

So I'm trying to use a MySqlDataReader to acquire data from my database. I know that the database does in fact respond (insert, delete, and update all work fine from my program).
using (MySqlConnection conn = new MySqlConnection(connectionString))
{
// Open a connection
conn.Open();
MySqlCommand command = conn.CreateCommand();
command.CommandText = "select * from cs3500_u0848199.PairedGames";
// Execute the command and cycle through the DataReader object
using (MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{ /*do something here*/}
}
}
The problem does not appear to be with the command itself, as the command works in the MySQL workbench. Anyways, upon executing this line of code
using (MySqlConnection conn = new MySqlConnection(connectionString))
the VS debugger notes that the following exception was thrown
System.FormatException was unhandled by user code
HResult=-2146233033 Message=Guid should contain 32 digits with 4
dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). Source=mscorlib
StackTrace:
at System.Guid.TryParseGuidWithNoStyle(String guidString, GuidResult& result)
at System.Guid.TryParseGuid(String g, GuidStyles flags, GuidResult& result)
at System.Guid..ctor(String g)
at MySql.Data.Types.MySqlGuid.MySql.Data.Types.IMySqlValue.ReadValue(MySqlPacket
packet, Int64 length, Boolean nullVal)
at MySql.Data.MySqlClient.NativeDriver.ReadColumnValue(Int32 index, MySqlField field, IMySqlValue valObject)
at MySql.Data.MySqlClient.Driver.ReadColumnValue(Int32 index, MySqlField field, IMySqlValue value)
at MySql.Data.MySqlClient.ResultSet.ReadColumnData(Boolean outputParms)
at MySql.Data.MySqlClient.ResultSet.NextRow(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlDataReader.Read()
at ToDoList.BoggleService.GetBriefStatus(String gameToken) in d:\repositories\x0848199\PS11\ToDoService\BoggleService.svc.cs:line
443
at SyncInvokeGetBriefStatus(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object
instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&
rpc) InnerException:
Really unsure as to why it's telling me about the guid format since i'm not using Guids in this code.
Any help will be greatly appreciated.
it appears that appending ;old guids=true; to the connection string resolved the issue.

When does "SqlConnection does not support parallel transactions" happen?

I have a ton of rather working code that's been here for months and today I saw the following exception logged:
System.InvalidOperationException
SqlConnection does not support parallel transactions.
at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(
IsolationLevel iso, String transactionName)
at System.Data.SqlClient.SqlConnection.BeginTransaction(
IsolationLevel iso, String transactionName)
at my code here
and I'd like to investigate why this exception was thrown. I've read MSDN description of BeginTransaction() and all it says is that well, sometimes this exception can be thrown.
What does this exception mean exactly? What is the deficiency in my code that I should be looking for?
You'll get this if the connection already has an uncommitted transaction and you call BeginTransaction again.
In this example:
class Program
{
static void Main(string[] args)
{
using (SqlConnection conn = new SqlConnection("Server=.;Database=TestDb;Trusted_Connection=True;"))
{
conn.Open();
using (var tran = conn.BeginTransaction())
{
using (var cmd = new SqlCommand("INSERT INTO TESTTABLE (test) values ('" + DateTime.Now.ToString() + "')", conn))
{
cmd.Transaction = tran;
cmd.ExecuteNonQuery();
}
using (var tran2 = conn.BeginTransaction()) // <-- EXCEPTION HERE
{
using (var cmd = new SqlCommand("INSERT INTO TESTTABLE (test) values ('INSIDE" + DateTime.Now.ToString() + "')", conn))
{
cmd.Transaction = tran2;
cmd.ExecuteNonQuery();
}
tran2.Commit();
}
tran.Commit();
}
}
}
}
... I get exactly the same exception at the second BeginTransaction.
Make sure the first transaction is committed or rolled back before the next one.
If you want nested transactions, you might find TransactionScope is the way forward.
The same problem occurs when using the 'wrong' method for a transaction, this happened after we upgraded to a newer version of the Entity Framework.
In the past we were using the following method to create a transaction and mixed EF strong typed linq queries with Sql queries, but since the Connection property did not exist anymore, we replaced all db. with db.Database, which was wrong:
// previous code
db.Connection.Open();
using (var transaction = db.Connection.BeginTransaction())
{
// do stuff inside transaction
}
// changed to the following WRONG code
db.Database.Connection.Open();
using (var transaction = db.Database.Connection.BeginTransaction())
{
// do stuff inside transaction
}
Somewhere they changed the behaviour of that transaction method behaviour with a newer version of the Entity Framework and the solution is to use:
db.Database.Connection.Open();
using (var transaction = db.Database.BeginTransaction())
{
// do stuff inside transaction
}
Notice that the transaction is now callen on Database instead of Connection.

using TransactionScope : System.Transactions.TransactionAbortedException: The transaction has aborted

We're trying to do indirect nesting transaction using the code below, .NET 3.5 ,& SQL Server 2005.
MSDN says that when using TransactionScope, a transaction is escalated whenever application opens a second connection (even to the same database) within the Transaction.
void RootMethod()
{
using(TransactionScope scope = new TransactionScope())
{
/* Perform transactional work here */
FirstMethod();
SecondMethod();
scope.Complete();
}
}
void FirstMethod()
{
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
using (SqlConnection conn1 = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI"))
{
string insertString = #"
insert into Categories
(CategoryName, Description)
values ('Laptop1', 'Model001')";
conn1.Open();
SqlCommand cmd = new SqlCommand(insertString, conn1);
cmd.ExecuteNonQuery();
}
scope.Complete();
}
}
void SecondMethod()
{
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
using (SqlConnection conn2 = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI"))
{
string insertString = #"
insert into Categories
(CategoryName, Description)
values ('Laptop2', 'Model002')";
conn2.Open(); //Looks like transactionabortedException is happening here
SqlCommand cmd = new SqlCommand(insertString, conn2);
cmd.ExecuteNonQuery();
}
scope.Complete();
}
}
Occasionally, the transaction fails that, is not promoting to DTC, and we are getting the following as the inner stack trace,
System.Transactions.TransactionAbortedException: The transaction has aborted. --->
System.Transactions.TransactionPromotionException: Failure while attempting to promote transaction. --->
System.InvalidOperationException: The requested operation cannot be completed because the connection has been broken.
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlDelegatedTransaction.Promote() --- End of inner exception stack trace ---
at System.Data.SqlClient.SqlDelegatedTransaction.Promote()
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
--- End of inner exception stack trace ---
at System.Transactions.TransactionStateAborted.CreateAbortingClone(InternalTransaction tx)
at System.Transactions.DependentTransaction..ctor(IsolationLevel isoLevel, InternalTransaction internalTransaction, Boolean blocking)
at System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption)
at System.Transactions.TransactionScope.SetCurrent(Transaction newCurrent)
at System.Transactions.TransactionScope.PushScope()
at System.Transactions.TransactionScope..ctor(TransactionScopeOption scopeOption)
Can anyone please help me figuring out the reason for this failure?
If you use TransactionScope and you:
open more than one connection to a database and
are connecting to a SQL Server 2005 server
the transaction will be escalated to DTC. Check this other SO question: TransactionScope automatically escalating to MSDTC on some machines?
The solution is either:
Use SQL Server 2008 or
Use SqlTransaction instead of TransactionScope just like the former answer suggests:
using (var conn = new SqlConnection(connectionString))
{
using (var tx = conn.BeginTransaction())
{
FirstMethod(conn);
SecondMethod(conn);
tx.Commit();
}
}
i can propose to you a better way to achieve your goal.
there should be a single transaction for 2 DB call per connection.
it should be like
using (SqlConnection conn1 = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI"))
{
using (conn1.BeginTransaction()
{
try
{
FirstMethod(Conn1);
SecondMethod(Conn2);
}
catch()
{
}
}
}

Categories

Resources