How can i connect remote sql server by Entity Framework? - c#

I have no enough experience on database systems. I have to connect to remote sql server and process some queries on it. How can i connect remote server by Entity Framework ?

1) Check if remote sql server is allowed remote connetions
2) In Visual Studio use Entity Framework wizard (add new connection)

Same as you would with any other database connection tool: Make sure the server and all firewalls/proxy servers between you and the server accepts the connection, and then supply EF with a correct connection string.
However, if you're only going to process some sql queries, I would suggest using SQL Server Management Studio instead. Entity Framework is an ORM, not a database management tool.

Here how I connect programmatically (no xml/appconfig file) to a remote server:
First check that your remote server is correctly parametrised. In particular one port has to be open. See this MSDN post for details.
Create the connection string as follow (see SqlConnectionStringBuilder):
public static string GetRemoteConnectionString()
{
SqlConnectionStringBuilder sqlString = new SqlConnectionStringBuilder()
{
DataSource = $"{IP},{PORT}", // ex : 37.59.110.55,1433
InitialCatalog = "MyDatabaseName", //Database
IntegratedSecurity = false,
MultipleActiveResultSets = true,
ApplicationName = "EntityFramework",
UserID = "MyUserId",
Password = "MyPassword"
};
return sqlString.ToString();
}
Then connect via the DbContext :
public class MDBContext : DbContext
{
public MDBContext () : base(GetRemoteConnectionString())
{
}
......
}
Extra :
You can also easily check connection (before to create the DbContext) as follow :
try
{
using (SqlConnection con = new SqlConnection(GetRemoteConnectionString()))
{
con.Open();
}
success = true;
}
catch (Exception ex)
{
success = false;
...
}

Related

C# DbContext Connection Type and Server

I have a WinForm application developed on one laptop connected to an SQL server on the same laptop.
I have a new laptop and have created a docker setup for an SQL server. I am looking to change the code base to use the new SQL server.
The new server is using SQL Server auth with username and password on the new laptop. The old laptop is using windows authentication on a windows installed setup. I have migrated a copy of the entire DB into my dockerised instance of the sql server.
The application has the connection settings in the app config and naturally this is for windows authentication.
My app.config is comitted to my github repository. I do not want to store the sql user/password in the app.settings, but instead I would like to get these from env variables I set on the machine.
I would also like to know how to change the format of the connection string in app.config so it works with sql server authentication.
Or maybe now I have explained what I am trying to do, there might be a better way?
My current connection strings are
<connectionStrings>
<add name="Blah.Properties.Settings.BlahConnectionString"
connectionString="Data Source=W.....R....;
Initial Catalog=Blah;
Integrated Security=True;
Connect Timeout=30;Encrypt=False;
TrustServerCertificate=False"
providerName="System.Data.SqlClient"/>
</connectionStrings>
[global::System.Data.Linq.Mapping.DatabaseAttribute(Name="Blah")]
public partial class BlahDBDataContext : System.Data.Linq.DataContext
I searched all code for 'AddDbContextFactory' and 'GetConnectionString'
public BlahDBDataContext() :
base(global::Blah.Properties.Settings.Default.BlahConnectionString, mappingSource)
{
OnCreated();
}
[global::System.Configuration.DefaultSettingValueAttribute("Data Source=PCNAME;Initial Catalog=Blah;Integrated Security=True" + ";Connect Timeout=30;Encrypt=False;TrustServerCertificate=False")]
public string BlahConnectionString
{
get { return ((string)(this["BlahConnectionString"]));
}
The database context class is generated code inheriting as far as I can tell on System.Data.Linq.DataContext, as shown by this code from my application.
[global::System.Data.Linq.Mapping.DatabaseAttribute(Name="Blah")]
public partial class BlahDBDataContext : System.Data.Linq.DataContext
{
The BlahDBDataContext class provides a number of constructors. Please check for yourself for a fuller list.
For my purposes the constructor I needed was
public BlahDBDataContext(System.Data.IDbConnection connection) :
base(connection, mappingSource)
{
OnCreated();
}
This requires the construction of a System.Data.IDbConnection object to hold/manage the connection details.
Therefore in my case all I needed to do was construct the connection string, for example.
string userName = EnvironmentVariables.GetValue("BLAH_USERNAME");
string password = EnvironmentVariables.GetValue("BLAH_PASSWORD");
string server = EnvironmentVariables.GetValue("BLAH_SERVER");
string database = EnvironmentVariables.GetValue("BLAH_DATABASE");
connectionString = $#"Data Source={server};Initial Catalog={database};Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;User ID={userName};Password={password};";
and then all thats needed is
new BlahDBDataContext(
new SqlConnection(
Program.GetDatabaseConnectionString()))
Where Program.GetDatabaseConnectionString() is.
public static string GetDatabaseConnectionString()
{
if (connectionString is null)
{
string userName = EnvironmentVariables.GetValue("BLAH_USERNAME");
string password = EnvironmentVariables.GetValue("BLAH_PASSWORD");
string server = EnvironmentVariables.GetValue("BLAH_SERVER");
string database = EnvironmentVariables.GetValue("BLAH_DATABASE");
connectionString = $#"Data Source={server};Initial Catalog={database};Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;User ID={userName};Password={password};";
}
return connectionString;
}
From a SOLID principles and clean coding perspective this is requires refactoring, and will be cleaned up now I have working code.

DB2 Connection string with SSL Server Certificate on .NET (Core)

I have been attempting to set up a DB2 Connection programmatically, via .NET, and I've puzzled with the following findings:
1. Testing a connection on VS Code
After installing the Db2 Connect extension, I've populated the following fields:
Database Name;
Host;
Port;
UserID;
Password;
and set the Checkbox Enable SSL Security = true, in addition to populating the full path of the SSL Server Certificated (saved on my local drive C:\...crt).
As a result, the Db2 connection has been established.
2. Testing a connection programmatically
After adding IBM.Data.DB2.Core as a reference into the project through NuGet, I've used in a Controller:
using System;
using IBM.Data.DB2.Core;
namespace SSLTest
{
class Program
{
static void Main()
{
DB2Command MyDB2Command = null;
String MyDb2ConnectionString = "database=alias;uid=userid;pwd=password;"; // nub of
//the issue
DB2Connection MyDb2Connection = new DB2Connection(MyDb2ConnectionString);
MyDb2Connection.Open();
MyDB2Command = MyDb2Connection.CreateCommand();
MyDB2Command.CommandText = "SELECT * from d.Test";
...
MyDb2DataReader.Close();
MyDB2Command.Dispose();
MyDb2Connection.Close();
}
}
}
To fully replicate programmatically the connection settings described in 1., I've used:
String MyDb2ConnectionString = "DATABASE=xxxxx;SERVER=xxxxx;UID=xxxx;PWD=xxxx;Security=SSL";
where SERVER = Hostand wonder on the way to add the SSL Server pathinto the connection string. Otherwise the connection would keep failing.
Thanks in advance.
Best

Azure function connect to on-premises sql access denied

I've got an issue where I cannot connect to an on-premises SQL database through an Azure function app once it is published to Azure. However when I run it locally in Visual Studio Code, it works perfectly.
The purpose of the Function is to resize images that are stored in Azure blob storage to a thumbnail and store it in a table field <varbinary(max)>.
Here is the error message I get:
2020-12-15T15:33:52.058 [Information] A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
2020-12-15T15:33:52.093 [Error] Executed 'BlobTrigger_MQS_Resize' (Failed, Id=346672c6-820c-43f6-b950-d5059e44697e, Duration=19570ms)
Access is denied.
I'm connecting to the SQL database via SQL Login, which works perfectly. Connection String is in local.settings.json:
{
"IsEncrypted": false,
"Values": {
...,
"Connection_SQL_Database_MQS": "Data Source=MyServer;Initial Catalog=MyDB;User ID=MyUser;Password=MyPassword;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
}
}
The code (in C#) which I have simplified a bit to the core of the issue:
public static class BlobTrigger_MQS_Resize
{
[FunctionName("BlobTrigger_MQS_Resize")]
public static async Task Run([BlobTrigger("mqs-media/{name}", Connection = "hqdevstorage_STORAGE")]Stream input, string name, ILogger log)
{
log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {input.Length} Bytes");
try
{
var connectionString = Environment.GetEnvironmentVariable("Connection_SQL_Database_MQS", EnvironmentVariableTarget.Process);
using (var output = new MemoryStream())
using (Image<Rgba32> image = Image.Load(input))
using (SqlConnection conn = new SqlConnection(connectionString))
{
// Code that resizes images to 'output', this works also when published
image.Resize(...);
image.Save(output, encoder);
//PROBLEM IS HERE: Write resized image to SQL Database
conn.Open();
var query = "UPDATE dbo.MyTable"
+ " SET Blob = #output"
+ " WHERE File_Name = '" + name + "'";
using(SqlCommand cmd = new SqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("#output", output);
var rows = await cmd.ExecuteNonQueryAsync();
log.LogInformation($"{rows} rows were updated");
}
}
}
catch (Exception ex)
{
log.LogInformation(ex.Message);
throw;
}
}
}
Can someone help me with this? I have no clue why it is working locally but not on Azure.
The server was not found or was not accessible.
This is a network connectivity issue, not a permissions issue. The Azure function cannot resolve your SQL Server's hostname into an IP address, and would not be able to connect to that IP address if it could.
Your function would need to access to an on-prem conected VNet or use a Hybrid Connection to reach your on-prem SQL Server.
see
https://learn.microsoft.com/en-us/azure/app-service/app-service-hybrid-connections
and
https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-vnet

Can't Connect C# with SQL Server

I am trying to write a program which interacts with my SQL Server database. I am programming in C# on Parallels on my Mac and SQL Server is running via Docker.
But I just can't connect. I am just getting the same error every time I try.
I have already tried to allow the remote access on SQL Server with:
EXEC sp_configure 'remote access', 1 ;
GO
RECONFIGURE ;
GO
but this does not solve my problem.
Here is my C# code:
main Class
Database database;
public Form1()
{
InitializeComponent();
database = new Database("localhost\\MSSQLSERVER", "user1", "topsecret", "master"); // \
}
private void connect_button_Click(object sender, EventArgs e)
{
database.Connect();
}
Database class:
class Database
{
SqlConnectionStringBuilder builder;
SqlConnection connection;
public Database(string source, string userid, string password, string initialcatalog){
this.builder = new SqlConnectionStringBuilder();
this.builder.DataSource = source;
this.builder.UserID = userid;
this.builder.Password = password;
this.builder.InitialCatalog = initialcatalog;
}
public void Connect()
{
try
{
// Connect to SQL
Console.WriteLine("Connecting to SQL Server ... ");
this.connection = new SqlConnection(this.builder.ConnectionString);
connection.Open();
Console.WriteLine("Connected");
}
catch(SqlException sqle)
{
Console.WriteLine(sqle.Message);
}
}
}
And I am always getting this error:
Network-related or instance-specific error when connecting to SQL Server. The server was not found or can not be accessed. Verify that the instance name is correct and that SQL Server allows remote connections. (provider: SQL Network Interfaces, error: 25 - connection string invalid)
The MSSQLSERVER is the instance name of the unnamed, default instance on your machine - you must not use this in the connection string.
Instead, try this line of code:
database = new Database("localhost", "user1", "topsecret", "master");
Just specify no explicit instance name at all - just localhost (or (local), or .) for the current machine - that's all you need!
It was Problem with Parallels, because Paralles can not access to localhost. So i had to define the IP from Parallels in Visual Studio like this:
database = new Database("10.211.55.2", "user1", "topsecret", "Time");

Cannot connect to Azure MySQL database from .NET Connector

I tried to connect to the Azure MySQL database using MySQL Workbench and MySQL Shell and it works fine. Now I am trying to connect using following C# code:
var connStringBuilder = new MySqlConnectionStringBuilder
{
Server = "creatur-db.mysql.database.azure.com",
Database = "test",
UserID = "creatur_db_main#creatur-db",
Password = "{my_password}",
SslMode = MySqlSslMode.Preferred,
};
using (MySqlConnection connection = new MySqlConnection(connStringBuilder.ToString()))
{
connection.Open();
connection.Close();
}
Here I replaced {my_password} with password to the database and it gives me an exception inside Open method:
MySql.Data.MySqlClient.MySqlException: 'Authentication to host
'creatur-db.mysql.database.azure.com' for user
'creatur_db_main#creatur-db' using method 'mysql_native_password'
failed with message: The connection string may not be right. Please
visit portal for references.
I also tried different connection strings:
Server=creatur-db.mysql.database.azure.com; Port=3306; Database=test; Uid=creatur_db_main#creatur-db; Pwd={my_password}; SslMode=Preferred
and
Database=test; Data Source=creatur-db.mysql.database.azure.com; User Id=creatur_db_main#creatur-db; Password={my_password}
But none of them worked.
The same exception occurs when I create new connection using Server Explorer in Visual Studio 2013. It seems the error has something to do with .NET Connector. I tried to use different versions of MySQL.Data.dll, .NET Framework and Visual Studio but no luck.
I just created a console application using VS2017 I used
Nuget package MySql.Data and .Net Framework 4.6.1
It works perfectly here What I did.
After Creating the MySQL server I used the CloudShell to connect to the SERVER (not a database).
Using this code:
mysql --host franktest.mysql.database.azure.com --user frank#franktest -p
I got an error
ERROR 9000 (HY000): Client with IP address '40.76.202.47' is not allowed to connect to this MySQL server.
So I add that IP and at the same time my IP from where I'm connected.
So once the IP were saved. I executed the previous command, and this time it worked perfectly. I created a database named: frankdemo using this command:
CREATE DATABASE frankdemo;
Then, back in VisualStudio used this code as my Main method, copied from the documentation.
static void Main(string[] args)
{
var builder = new MySqlConnectionStringBuilder
{
Server = "franktest.mysql.database.azure.com",
Database = "frankdemo",
UserID = "frank#franktest",
Password = "gr3enRay14!",
SslMode = MySqlSslMode.Required,
};
using (var conn = new MySqlConnection(builder.ConnectionString))
{
Console.WriteLine("Opening connection");
conn.Open();
using (var command = conn.CreateCommand())
{
command.CommandText = "DROP TABLE IF EXISTS inventory;";
command.ExecuteNonQuery();
Console.WriteLine("Finished dropping table (if existed)");
command.CommandText = "CREATE TABLE inventory (id serial PRIMARY KEY, name VARCHAR(50), quantity INTEGER);";
command.ExecuteNonQuery();
Console.WriteLine("Finished creating table");
command.CommandText = #"INSERT INTO inventory (name, quantity) VALUES (#name1, #quantity1),
(#name2, #quantity2), (#name3, #quantity3);";
command.Parameters.AddWithValue("#name1", "banana");
command.Parameters.AddWithValue("#quantity1", 150);
command.Parameters.AddWithValue("#name2", "orange");
command.Parameters.AddWithValue("#quantity2", 154);
command.Parameters.AddWithValue("#name3", "apple");
command.Parameters.AddWithValue("#quantity3", 100);
int rowCount = command.ExecuteNonQuery();
Console.WriteLine(String.Format("Number of rows inserted={0}", rowCount));
}
// connection will be closed by the 'using' block
Console.WriteLine("Closing connection");
}
Console.WriteLine("Press RETURN to exit");
Console.ReadLine();
}
Runed it and it works
The documentation I'm referring to is:
Create an Azure Database for MySQL server by using the Azure portal
Azure Database for MySQL: Use .NET (C#) to connect and query data

Categories