-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Don't check for a connection string until after ConnectionOpening has been called #23085
Comments
The code sample below uses a connection interceptor to successfully modify the connection string before the connection is opened (in a way that makes the open fail). If you're still running into difficulties, can you please post a runnable code sample? Code sampleawait using var ctx = new BlogContext();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();
_ = ctx.Blogs.ToList();
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
static ILoggerFactory ContextLoggerFactory
=> LoggerFactory.Create(b => b.AddConsole().AddFilter("", LogLevel.Information));
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlite("Filename=:memory:")
.EnableSensitiveDataLogging()
.UseLoggerFactory(ContextLoggerFactory)
.AddInterceptors(new MyInterceptor());
}
class MyInterceptor : DbConnectionInterceptor
{
public override InterceptionResult ConnectionOpening(
DbConnection connection,
ConnectionEventData eventData,
InterceptionResult result)
{
Console.WriteLine("Intercepting");
connection.ConnectionString += ";Foo=Bar";
return result;
}
}
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
} |
@roji thanks but the sample provided is adding settings to the connection string after; I wish to supply a connection string with extra settings and then use these inside the interceptor and remove them so the connection can then be created. If you modify you sample to have the Foo=Bar on the original connection string and have the interceptor remove this; that would be the correct type of implementation. However this would throw an exception as the connection string is not valid at point of creating the connection object; therefore I feel a CreatingConnection is required. |
@3GDXC I don't follow... the code sample above modifies the connection string - it happens to be adding a keyword, but it could just as well perform any sort of manipulation on the connection string. You can set it to some other string, or parse the given string with SqliteConnectionStringBuilder, make changes on that, and assign the resulting string back. More generally, a connection string can be assigned to DbConnection.ConnectionString at any point after the DbConnection is instantiated. It only has to happen before that connection is opened, in order for it to be taken into account. That's why I'm not clear on what CreatingConnection would add here compared to the existing ConnectionOpening. |
@roji it seems that the ConnectionString is getting validated before the ConnectionOpening is called? as if you supply a connection string with extra key/value pairs (that aren't supported by the real conneciton) but would be used by the interceptor the interceptor ConnectionOpening never gets called ? |
Are you saying that the original connection string (before any interceptor gets involved) is invalid, and you're trying to correct it with an interceptor? This would indeed not work with ConnectionOpening, but IMHO it's strange to want to deal with this via interception... Can you please provide more context on what you need to do? |
@roji yes, lets correct I would like to provide the interceptor some options for configuration; these options extend the options that are available on the providers connection string ie. WASM=true; culture=en-gb; would add WASM support to the connection and is the browser culture en-gb these options are NOT valid for the original connection provider, but solely for the interceptors as you are able to add addition key/value pairs to a connection string at the point 'ConnectionOpening' I would have expected to be able to remove key/value pairs also at this point prior to the opening of the connection; I would also expect that the connection string would be validate after this point by the original provider connection. Therefore the interception could grab/correct/modify the connection string just prior to opening removing invalid values and/or values that are not intended for the connection provider. @roji I hope trust this gives a better description of what I'm trying to do? |
@3GDXC thanks for explaining, I'll take a deeper look at this (and your code sample) in the coming days. |
Note for triage: I investigated this and even though 5.0 allows the connection string to be mutated in ConnectionOpening, a valid connection string must still be initially supplied. This is unfortunate given that an empty connection string is invalid, which means doing |
@bricelam @roji Found the source of confusion on the empty connection string issue: we throw from EF if the connection string is empty. We can likely move this check until after ConnectionOpening.
|
Thanks @ajcvickers, makes sense! |
@ajcvickers , In multi tenant systems, connection string is often not known until Tenant is resolved. How do you suggest we tacklet his scenario? |
@maulik-modi Implementation of this issue would be a good start. |
Instead, let ADO.NET validate. This allows the connection string to be set as late as possible, for example in the ConnectionOpening interceptor. Fixes #23085
Instead, let ADO.NET validate. This allows the connection string to be set as late as possible, for example in the ConnectionOpening interceptor. Fixes #23085
File a bug
using a connection interceptor I would expect that you should be able intercept prior to the connection string validation and/or before any logic is performed with regards to establishing a connection is performed.
at present the connection string is evaluated before the interceptor and therefore any additional information provided/added to the connection string for the interceptor is rejected,
The text was updated successfully, but these errors were encountered: