We have a need to use an old fashioned ADO database connection in one tiny part of the main entity framework application.
We can manually specify the connection string in this part of code, but given that the connection string is already present in the App.Config this seems redundant.
However when we use the configuration manager to retrieve the connection string, it brings with it all of the metadata stuff that entity framework uses.
This causes an error as ADO doesnt recognise the metadata keyword.
How can I parse this connection string to remove the metadata and just get the plain ADO connection string?
You can get DbConnection instance from DbContext:
var context = new YourDbContext();
var connection = context.Database.Connection;
Of course, you can get connection string from connection, but you don't need thus you can use already existing connection object.
Here is Quick Watch of connection object - as you can see it's simple ADO.NET SqlConnection object with ordinal connection string.
In config file I have Entity Framework connection string with metadata:
<connectionStrings>
<add name="NorthwindEntities"
connectionString="metadata=res://*/Northwind.csdl|res://*/Northwind.ssdl|res://*/Northwind.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=Northwind;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
Below should work :
var efConn = new System.Data.EntityClient.EntityConnectionStringBuilder(efConnection);
string adoConn = efConn.ProviderConnectionString;
I was trying to the same and ended up using this approach:
private static string RemoveEntityFrameworkMetadata(string efConnection)
{
int start = efConnection.IndexOf("\"", StringComparison.OrdinalIgnoreCase);
int end = efConnection.LastIndexOf("\"", StringComparison.OrdinalIgnoreCase);
// We do not want to include the quotation marks
start++;
int length = end - start;
string pureSqlConnection = entityFrameworkConnection.Substring(start, length);
return pureSqlConnection;
}
This may not be the most elegant solution, but it works.
(I also tried Regex but can't get my head around it.)
Related
I'm connecting to Firebird Database using C#
I can't find where to check the ConnectionState to the database
If I make new fbConnection inside project it's easy to check it by fbConnection.ConnectionState
but I have made this connection with wizard and it's saved in App.config file
I tried to use System.Configuration.ConfigurationManager but it doesn't have ConnectionState
So how can I check connection state that defined in App.config file.
It seems that you don't understand how this thing (the connection) works or what it is. The ConfigurationManager class just helps you to retrieve the connectionstring (note the word string. It is just a string nothing more).
With this string you can build your real instance of an FBConnection and try to open that connection. Now you could check the ConnectionState.
So
string connectionString = ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
using(FbConnection myConnection = new FbConnection(connectionString))
{
// At this point the myConnection instance is certainly closed so
// it is total useless to check the ConnectionState
myConnection.Open();
// At this point the myConnection instance is certainly opened,
// otherwise you get an exception and your code cannot contine,
// so also here it is useless to check the ConnectionState
// however...
if(myConnection.ConnectionState == ConnectionState.Open)
{
.... do your stuff with the connection.....
}
}
For this code to work you need to have in your App.Config the appropriate section where you store the details required to connect to your database under the symbolic name "MyConnection"
<connectionStrings>
<add name="MyConnection" connectionString="Data Source=localhost;
Database=YourDatabaseFile.fdb;
User=YourUserName;
Password=????whatever???;
Pooling=True" />
</connectionStrings>
So I really have never needed to check the connection state of a connection. The only possible use if this property is when you want to keep a global connection instance and in various part of your code you need to check the ConnectionState before trying to open or close this global instance. This scenario is not the best way to work with a disposable object like the connection that should be opened for the shortest period of time possible and the immediately destroyed (disposed) And exiting from the using block disposes the connection.
Check out this link, it may be useful for you.
https://sourceforge.net/p/firebird/NETProvider/ci/0475d606c597498a99be50393646c1c92d773dd4/tree/examples/ASP.NET/web.config
I have the following type of code in my data layer, which can be called from a console app, windows app, etc, with the proper connection string being read from the corresponding caller's App.Config file:
public static udsDataset GetDataset(int datasetID)
{
string connectionString =
ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string sql = #"select * from Dataset WHERE DatasetID=#datasetID";
using (SqlConnection conn = new SqlConnection(connectionString))
{
// Dapper query:
return conn.Query<udsDataset>(sql, new {datasetID } ).First();
}
}
I now want to call this same code from a SQLCLR stored procedure (within the database where these tables exist), where you would typically use a context connection:
using(SqlConnection connection = new SqlConnection("context connection=true"))
{
connection.Open();
// etc etc etc
}
The most obvious approach that comes to mind is to overload the function:
public static udsDataset GetDataset(int datasetID)
{
string connectionString =
ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connectionString))
{
return GetDataset(datasetID, conn);
}
}
public static udsDataset GetDataset(int datasetID, SqlConnection conn)
{
// caller is responsible for closing and disposing connection
string sql = #"select * from Dataset WHERE DatasetID=#datasetID";
return conn.Query<udsDataset>(sql, new {datasetID } ).First();
}
So apps with an App.Config could call the connection-less version and SQLCLR could call the version requiring a SqlConnection.
This "seems ok", but having to write the exact same style of overload for every single similar function makes it feel wrong.
Taking the question (and comments on it) at face-value, why do you need:
the option of passing in an existing connection when calling from a SQLCLR procedure
? You should treat the Context Connection the same as any other connection with regards to Open and Dispose. It sounds like you are thinking that the SqlConnection, when using a Connection String of "Context Connection = true;", needs to be opened only once and then not disposed until completely done, whereas you would Open / Dispose of it several times otherwise. I don't see any reason to have differing behavior in these two scenarios.
All of that aside, how to best handle detecting the change in environment (between Console App and SQLCLR object)? You have two choices, both being probably easier than you are expecting:
Make no changes to the app code, but rely on an additional config file:
You can create a file named sqlservr.exe.Config in the C:\Program Files\Microsoft SQL Server\MSSQL{SqlVersion}.{SqlServerInstanceName}\MSSQL\Binn folder (e.g. C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Binn, where the 11 in MSSQL11 is for SQL Server 2012). The format of this file, as should probably be expected, is as follows:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="CoolioAppDB" connectionString="Context Connection = true;" />
</connectionStrings>
</configuration>
This might be considered "cleaner" code, but does introduce an external dependency that your DBA might be ok with, might dislike but tolerate, or might ask your manager to write you up for ;-).
Make a very minor change to the app code, but don't rely on an additional config file:
You can easily auto-detect whether or not you are currently running in SQL Servers's CLR host by using the IsAvailable property of the SqlContext class. Just update your original code as follows:
string connectionString = "Context Connection = true;"; // default = SQLCLR connection
if (!SqlContext.IsAvailable) // if not running within SQL Server, get from config file
{
connectionString =
ConfigurationManager.ConnectionStrings["CoolioAppDB"].ConnectionString;
}
This usage, by the way, is noted in the "Remarks" section of that linked MSDN page for the IsAvailable property.
I'm trying to connect to a mySQL database from C# application but getting the following error.
Keyword not supported: 'database'.
The mySQL.Net connector version is 6.9.6
Following is the connection string in my app.config file.
<connectionStrings>
<add name="ABC.DAL.CONN.MySql" providerName="DataProvider.MySql" connectionString="SERVER =MyServer; database =my_database; UID =admin; Pwd =Dba49!;"/>
</connectionStrings>
Following is the piece of code that connects to MySQL database for bulkinsert -
MySqlConnection mySqlConn = new MySqlConnection(dbConnString);
MySqlBulkLoader obSBC = new MySqlBulkLoader(mySqlConn);
obSBC.Columns.Add("CUSTOMER_ID");
obSBC.Columns.Add("VEHICLE_NUMBER");
obSBC.TableName = "TX_CUSTOMER";
obSBC.FieldTerminator = #",";
obSBC.FileName = strFilePath + strFileName;
obSBC.NumberOfLinesToSkip = 0;
obSBC.Priority = MySqlBulkLoaderPriority.None;
obSBC.Timeout = 2000;
obSBC.ConflictOption = MySqlBulkLoaderConflictOption.None;
int countRecords = obSBC.Load();
I checked a lot of forums but unable to resolve the error.
There is an old bug in MySQL that under certain conditions makes connection strings case sensitive. AFAIK I know this has never been fixed.
Please try deleting all the whitespaces from your connection string and write the keyword Database (and it's value, if that is in Caps too) in Caps.
I am going off of this tutorial: http://www.dotnetperls.com/sqlclient . Instead of adding a data source and a having visual studio compile my connecting string - I want to do it myself. The reason being is that the database will not always be the same and I want this application to be able to use different databases depending on which I point it to.
So how can I manually create the connection string? I am using SQL Server 2005.
Step 1: Go to connectionstrings.com and find the proper format for your database.
Step 2: Plug in the appropriate values to the connection string.
Step 3: Pass that string to the constructor of SqlConnection.
I would also suggest storing your connection string in your app.config/web.config file. You can then modify them easily if needed. The proper format can be found at MSDN - connectionStrings element. You then change your code to:
SqlConnection sqlConn = new SqlConnection(
ConfigurationManager.ConnectionStrings["ConnStringName"].ConnectionString);
I don't see where the connection string is "compiled".
In the code
SqlConnection con = new SqlConnection(
ConsoleApplication1.Properties.Settings.Default.masterConnectionString)
ConsoleApplication1.Properties.Settings.Default.masterConnectionString is a field and it can be replaced with any other appropriate string.
for SQL Server format of the connection string is
"Data Source = server_address; Initial Catalog = database_name; User ID = UserId; Password = **;"
save this connection string in a string variable and use with connection object.
either way you can add in web.config file.
<ConnectionString>
<add name = "name_of_connecctionString" ConnectionString = "Data Source = server_address; Initial Catalog = database_name; User ID = UserId; Password = ****;" ProviderName = "system.Data.SqlClient"/>
</ConnectionString>
you can change the provider as needed by you.
then in code behind file access this particular connection string using configuration manager.
I have a following connection string in app.config
<add name="myDBConnectionString"
connectionString="Data Source=ASDFG\SQLEXPRESS;
Initial Catalog=ZAQ;
Integrated Security=True;"/>
in my C# code then, when I get this string DB is always evaluated as "ASDFG\\SQLEXPRESS"
I couldn't put # since app.config doesn't like it. Also, if I say
ASDFG\\SQLEXPRESS
it gets evaluated as
ASDFG\\\\SQLEXPRESS
and not open the connection.
Thank You,
The debugger may display it as ASDFG\\SQLEXPRESS, but it's just escaping that backslash for display purposes.
use this in codebehind
string conString =
System.Configuration.ConfigurationManager
.ConnectionStrings["myDBConnectionString"].ToString();
always evaluated as "ASDFG\SQLEXPRESS"
Which is quite correct. Any actual problems opening the Db?