EF Core 3.0 Manually setting connection string

0

I'm developing a console app with .NET Core & EF Core (both are v3.0); and I need to start my DbContext using an string generated from another class.

DbContext file

public Arta_LuniaDBContext() { }

public Arta_LuniaDBContext(DbContextOptions<Arta_LuniaDBContext> options) : base(options) { }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
   optionsBuilder.UseSqlServer(DataServices.ConnectionString);
}

DataServices class

public static string ConnectionString { get { return GetConnectionData(); } }

private static string GetConnectionData()
{
   /// Sets the Server name, Database, UserId and Password.
   string Server, Database, UserId, Password;

   /// Sets the separator.
   string Separator = ";";

   /// Connection string [internal].
   string ArtaConn = null;

   /// Loads Settings.xml
   XmlDocument xDoc = new XmlDocument();
   xDoc.Load("Settings.xml");

   /// Gets the XmlNode: DataSource
   XmlNodeList xSource = xDoc.GetElementsByTagName("DataSource");
   for (int i = 0; i < xSource.Count; i++)
   {
      /// Sets the Server name.
      Server = "Server=" + xSource[i].Attributes["Server"].Value + Separator;

      /// Sets the Database.
      Database = "Database=" + xSource[i].Attributes["Database"].Value + Separator;

      /// Sets the User id.
   UserId = "User id=" + xSource[i].Attributes["UserId"].Value + Separator;

      /// Sets the Password.
      Password = "Password=" + xSource[i].Attributes["Password"].Value + Separator;

      /// Builds the connection string.
      ArtaConn = Server + Database + UserId + Password;
      Colorful.Console.WriteLine(ArtaConn, System.Drawing.Color.Yellow);
      // I'm using this line to test the output.
   }

   /// Returns~
   return ArtaConn;
}

Settings.xml

<!-- Sets the Database ConnectionString -->
<DataSource Server="IP_ADDRESS\\INSTANCE" Database="DbName" UserId="MyUser" Password="MyPassword" />

ConsoleWrite line shows my output as:

Server=IP_ADDRESS\\INSTANCE;Database=DbName;User id=MyUser;Password=MyPassword;

And this string seems okay for me but, when I try to connect to the database, I'm getting the following error:

System.Data.SqlClient.SqlException (0x80131904): 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: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)

Strange enough, if I set:

optionsBuilder.UseSqlServer("IP_ADDRESS\\INSTANCE;Database=DbName;User id=MyUser;Password=MyPassword;");

I can connect without any problem…

Is there any way to fix it? Thanks in advance.

[Edit] Fixed it; Changed:

<DataSource Server="IP_ADDRESS\\INSTANCE" Database="DbName" UserId="MyUser" Password="MyPassword" />

To:

<DataSource Server="IP_ADDRESS\INSTANCE" Database="DbName" UserId="MyUser" Password="MyPassword" />
c#
sql-server
entity-framework
.net-core
asked on Stack Overflow Feb 1, 2019 by Amanda Gonçalo • edited Feb 2, 2019 by Amanda Gonçalo

2 Answers

1

review the used of backslashes in your xml file.

in some contexts, \\ can be an escaped \, as a literal, it is 2 slashes.

This code illustrates the point: These string are not equal.

        String s= "Server=IP\\INSTANCE_NAME;Database=db;User id=User ;Password=pwd;";
    String s2= @"Server=IP\\INSTANCE_NAME;Database=db;User id=User ;Password=pwd;";

    Console.WriteLine(s2== s);

If you try this with localhost, does it work the way you expect? if so: the culpurit is the .

you can also see if this works.

optionsBuilder.UseSqlServer(@"Server=Server=IP\\INSTANCE_NAME;Database=DB;User id=User ;Password=pwd;");

Hope this helps!

answered on Stack Overflow Feb 1, 2019 by brian chandley • edited Feb 1, 2019 by brian chandley
0

Use right tool for the job - SqlConnectionStringBuilder Class
Builder will escape backslashes and build proper connection string for Sql Server connection.

var builder = new SqlConnectionStringBuilder
{
    DataSource = @"IP_ADDRESS\INSTANCE",
    InitialCatalog = "DbName",
    UserID = "MyUserId",
    Password = "MyPassword"
};

var connectionString = builder.ConnectionString;

// Use connection string
optionsBuilder.UseSqlServer(connectionString );

So your method can look like below:

private SqlConnectionStringBuilder BuilderFromElement(XElement source)
{
    return new SqlConnectionStringBuilder
    {
        DataSource = source.Attribute("Server")?.Value,
        InitialCatalog = source.Attribute("Database")?.Value,
        UserID = source.Attribute("UserID")?.Value,
        Password = source.Attribute("Password")?.Value
    };
}

private string GetConnectionString()
{
    var settings = XDocument.Load("Settings.xml");
    var allConnectionStrings = 
        settings.Descendants("DataSource")
                .Select(BuilderFromElement)
                .Select(builder => builder.ConnectionString)

    return allConnectionStrings.FirstOrDefault();
}
answered on Stack Overflow Feb 1, 2019 by Fabio • edited Feb 1, 2019 by Fabio

User contributions licensed under CC BY-SA 3.0