从 DbConnection 获取 SqlConnection

34

我在DbContext上拥有一个扩展方法,想要执行SqlBulkCopy。因此,我需要一个SqlConnection。然而,从DbContext获取的连接类型是DbConnection。 在我尝试的几种方法中,包含以下内容:

var connection = new SqlConnection( dbContext.Database.Connection.ConnectionString);

问题在于密码丢失(可能是出于安全原因)。

我尝试的另一件事是向上转换:

var bulk_copy = new SqlBulkCopy( (SqlConnection)dbContext.Database.Connection );

这实际上假设了 DbConnection 是一个 SqlConnection。在这种非常特殊的情况下,它已经出现了问题。我正在使用 MVC MiniProfiler 将连接包装到 EFProfiledDbConnection 中。EFProfiledDbConnection 没有继承自 SqlConnection。

还有其他的想法吗?提前感谢!


不,无论是SqlConnection还是SqlBulkCopy都不接受DbConnection作为构造函数参数。 - Dirk Boer
1
尝试将 DbConnection 强制转换为 SqlConnection - Wiktor Zychla
抱歉,我已经尝试过了,但是忘记将其添加到问题中。我已经更新了我的问题。 - Dirk Boer
那么请尝试我的方法 - 看看我的答案。 - Wiktor Zychla
8个回答

20

好的,如果两者可以共享同一个连接字符串(Connection String),那么我猜它们都是SqlConnection

试试这个:

var connection = rep.Database.Connection as SqlConnection;

抱歉,我之前已经尝试过了,但是忘记将其添加到问题中。我已经更新了我的问题。 - Dirk Boer
10
对于任何未来查看此问题的浏览者。尽管这个答案对于原帖作者无效,但通常情况下DbConnection通常是SqlConnection的实例。因此,您应该检查并确定这是否适用于您的特定实例。 - Mark Rucker

7

解决这个问题的一种可能方法是在您的连接字符串中添加Persist Security Info=true


我并不是非常熟悉Persist Security Info。它听起来有点过于激烈,对于希望能更优雅地解决的问题而言。它有哪些缺点? - Dirk Boer
1
Persist Security Info会在内存中保留您的密码,否则它会被擦除,从而使您重复使用连接字符串变得不可用。我认为您不必担心任何缺点,假设连接字符串是在配置文件中提供的。 - Wiktor Zychla
1
最优雅的方法是切换到集成安全性,这样在连接字符串中就没有用户名/密码,而是使用 Integrated security=true - Wiktor Zychla
好的,我会看一下!由于我使用SQL Azure,集成安全性是不可能的。 - Dirk Boer
将安全信息持久化存储几乎没有风险。或者说,风险仅仅是理论上的。 - Wiktor Zychla

4

我曾遇到和ProfiledConnection (HibernatingRhinos.Profiler.Appender.ProfiledDataAccess.ProfiledConnection)类似的问题。

我需要的是SqlConnection,以下代码解决了我的问题:

ProfiledConnection profiledConnection = dbContext.Database.Connection as ProfiledConnection;
SqlConnection sqlConnection = (SqlConnection)profiledConnection.Inner;

3

迄今为止我发现的唯一方法是使用System.Configuration库:

var sqlConnString = ConfigurationManager.ConnectionStrings["your_conn_string_name"].ConnectionString;
var bulkCopy = new SqlBulkCopy(sqlConnString);

1
有时候,由于事务原因,您希望使用现有的连接。 - gsharp

3
如果您正在使用更新的.NET Core:
new SqlConnection(kontext.Database.GetConnectionString())

1
你可以检查 dbContext.Database.Connection 的类型。如果它是 EFProfiledDbConnection,那么你可以获取它的 WrappedConnection 属性,该属性返回一个 DbConnection。如果你使用 SQL Server,那么它就是一个 SqlConnection

如果真的没有其他解决方案,我可能会这样做。但我认为这很丑陋。检查类型就像是糟糕的代码味道,而且我宁愿避免这种情况。这也意味着在此程序集中添加对MiniProfiler的引用(现在只在我的Web程序集中引用MiniProfiler)。另一个缺点是未来可能会有另一种类型的DbConnection,我没有考虑到,代码会再次出错。 - Dirk Boer
你可以将其包装在上下文本身中,例如在 GetConnection() 方法中。其他程序集不需要引用 MiniProfiler。 - Gert Arnold

-2
你可以使用这个:
SqlConnection sqlConn = dbContext.Database.GetConnection<SqlConnection>()

-3

您可以使用:

(SqlConnection)context.Database.GetDbConnection()

这将创建一个包含密码的 SQL 连接对象的副本。


1
获取此DbContext的基础ADO.NET DbConnection。问题说明他们不想要这个连接。 - Gert Arnold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接