-
Notifications
You must be signed in to change notification settings - Fork 285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LocalDB shared instance not supported #1231
Comments
@gkeongit sorry for the delay. I am looking into this issue and will provide more information shortly. |
Here is a description on how I ran the code for those who want to follow:
Continue either on SSMS or CLI with SqlCmd: for SSMS use (localdb)\your instancename @gkeongit please make sure you have done the following: More immportant part class Program
{
static async Task Main(string[] args)
{
var builder = new SqlConnectionStringBuilder()
{
DataSource = "(localdb)\\.\\OurInstance",
IntegratedSecurity = true,
ConnectTimeout=30,
Encrypt=false,
TrustServerCertificate=false,
ApplicationIntent=ApplicationIntent.ReadWrite,
MultiSubnetFailover=false
};
using var connection = new SqlConnection(builder.ConnectionString);
var cts = new CancellationTokenSource();
await connection.OpenAsync(cts.Token).ConfigureAwait(false);
Console.WriteLine(connection.State);
}
} And this will work perfectly with no issue. In VS2019 you can go to view tab and select Please let me know if there is any issue after granting access to user, otherwise we can close the issue. |
Thank you very much for your support. I have tried to follow the proposed steps, because I set up my user with SSMS and wanted to see, if it makes a difference using SQL CLI. But both SQL commands give me syntax errors. E.g. to create the login, I have to append
And I could not figure out, what the exact syntax of the GRANT command would be. Anyway: in my case, I think I already did the required steps in SSMS. Hence, I can use Server Object Explorer in VS2019 and also SSMS with my shared instance and with the original instance. And I can confirm, that your code example is running fine on my machine. But it is obviously running with a different user account (in my case: the DB owner account), what seems to change the outcome. So here are details about the user that runs into the error. It is an IIS AppPool user ('Token Service'), since my application is an ASP.NET Core web application hosted in IIS. It has a login on the server: And it is linked to a database user, to which I now granted a lot of rights just to test this issue: But I still have the same error. Please let me know, if I am missing a thing here. Also, I assume your test case cannot pass the SqlClient code I mentioned, because if you try this (based on original SqlClient condition)... const string LocalDbHost = "(localdb)";
string[] tokensByBackSlash = "(localdb)\\.\\OurInstance".Split('\\');
// All LocalDb endpoints are of the format host\instancename where host is always (LocalDb) (case-insensitive)
if (tokensByBackSlash.Length == 2 && LocalDbHost.Equals(tokensByBackSlash[0].TrimStart()))
{
Console.WriteLine($"Recognized localdb instance '{tokensByBackSlash[1]}'");
}
else
{
Console.WriteLine("Not a localdb instance");
} ...you will see, that (localdb)\.\OurInstance is not recognized as LocalDB instance. In that case, SqlClient takes the string as servername, which leads to |
@gkeongit I think the length of if (tokensByBackSlash.Length == 3 && LocalDbHost.Equals(tokensByBackSlash[0].TrimStart()))
{
Console.WriteLine($"Recognized localdb instance '{tokensByBackSlash[2]}'");
}
else
{
Console.WriteLine("Not a localdb instance");
} Is this what we are looking for or I missed something in the explanation? |
one more question are you using managed SNI by any chance? |
@JRahnama About the code change: It should be tokensByBackSlash.Length >= 2 Otherwise we would exclude the non-shared instance names that resolve to two tokens. About the managed SNI: Yes, you are right! I forgot about it, but in an attempt to solve another issue, I followed an advice to use: AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true); And this was still in my code. After removing this, I can connect to the shared instance with my IIS AppPool user, too. |
@gkeongit I noticed the issue in managed SNI. Basically it assumes the array is always in a size of 2 and that creates the problem. |
@JRahnama my test failed, but it looks like we just need to retain the leading '.\' of the shared instance name. I could connect to
with this change: diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs
index bf4831f7..52bc18b2 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs
@@ -493,13 +493,9 @@ namespace Microsoft.Data.SqlClient.SNI
// When netcoreapp support for netcoreapp2.1 is dropped these slice calls could be converted to System.Range\System.Index
// Such ad input = input[1..];
input = input.Slice(LocalDbHost.Length);
- if (!input.IsEmpty && input[0] == '\\')
+ if (!input.IsEmpty && input[0] == BackSlashCharacter)
{
input = input.Slice(1);
- if (input.Length >= 2 && input[0] == '.' && input[1] == BackSlashCharacter)
- {
- input = input.Slice(2);
- }
}
if (!input.IsEmpty)
{
|
@gkeongit, let's review the case again:
These three scenarios should be working with the change and the failure is about the 3rd part in your list? is that correct?
like we provide |
What is |
@ErikEJ I forgot to wrap it as code and GitHub do not show it. (localdb). and More to add if you use <> in your comment, the insid it will be hidden if you do not wrap it as code. There is a comment here if you try to edit :=====> |
OK, but what is |
Interesting! |
Yes, exactly. It is the case, which must not be recognized as localdb instance name. Hence, the method must return
The failure is on the explicit shared instance syntax only: |
@gkeongit |
@JRahnama sorry, if I added confusion with my testcases. I absolutely agree to your explanation and I am aware of Let us focus on the
but it should be
Please compare to my proposal, where I removed the unwanted final - if (input.Length >= 2 && input[0] == '.' && input[1] == BackSlashCharacter)
- {
- input = input.Slice(2);
- } I think, if you remove this block in PR #1237, it should work. |
I can confirm your suggestion was correct. I have applied your requested changes to the PR and it should be working. Please let me know of the results. For those who are following: if you run |
Thank you, that's it! With this artifact I could successfully connect to shared instance. |
Connection to a shared instance of localdb fails. Shared instances use names in format '.\name'. Hence, a connection string contains a datasource like '(localdb)\.\name' with two backslashes.
But here the assumption is made, that splitting the datasource value by backslash yields exactly two tokens.
Exception message
The exception message is a bit misleading. The initial error is, that the datasource name is not recognized as a LocalDB instance.
Stack trace
To reproduce
Try to connect to a shared instance. From what I saw, it does not even have to exist to let you reproduce the error. Just use a connection string with the '.\name' syntax:
Expected behavior
The data source should be recognized as LocalDB instance.
Further technical details
Microsoft.Data.SqlClient version: 3.0.0
.NET target: 5.0
SQL Server version: 15.0.4153 with cumulative update SQLServer2019-KB5004524-x64.exe installed
Operating system: Windows 10 Pro, version 2004, build 19041.1165
The text was updated successfully, but these errors were encountered: