我已经学习了很多浏览C#的隐藏功能,当我找不到类似于VB.NET的东西时,我感到很惊讶.
那么它的一些隐藏或鲜为人知的特征是什么?
我有一个数据DataReader,我希望将其转换为List<T>.对此有什么简单的解决方案?
例如,在CustomerEntity类中,我有CustomerId和CustomerName属性.如果我的DataReader将这两列作为数据返回,那么我该如何将其转换为List<CustomerEntity>.
有没有一种正确的方法可以打破foreach,以便IEnumerable <>知道我已经完成并且应该清理它.
请考虑以下代码:
private static IEnumerable<Person> getPeople()
{
using (SqlConnection sqlConnection = new SqlConnection("..."))
{
try
{
sqlConnection.Open();
using (SqlCommand sqlCommand = new SqlCommand("select id, firstName, lastName from people", sqlConnection))
{
using (SqlDataReader reader = sqlCommand.ExecuteReader())
{
while (reader.Read())
yield return new Person(reader.GetGuid(0), reader.GetString(1), reader.GetString(2));
}
}
}
finally
{
Console.WriteLine("finally disposing of the connection");
if (sqlConnection.State == System.Data.ConnectionState.Open)
sqlConnection.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果他的消费者没有脱离foreach,那么everthing很好并且读者将返回false,while循环willend并且该函数清除数据库命令和连接.但是如果在我结束之前呼叫者从foreach断开会发生什么呢?
我们有很多数据层代码遵循这个非常通用的模式:
public DataTable GetSomeData(string filter)
{
string sql = "SELECT * FROM [SomeTable] WHERE SomeColumn= @Filter";
DataTable result = new DataTable();
using (SqlConnection cn = new SqlConnection(GetConnectionString()))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@Filter", SqlDbType.NVarChar, 255).Value = filter;
result.Load(cmd.ExecuteReader());
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我想我们可以做得更好一点.我现在的主要抱怨是它强制将所有记录加载到内存中,即使对于大型集合也是如此.我希望能够利用DataReader的能力,一次只能在ram中保留一条记录,但如果我直接返回DataReader,则在离开using块时会切断连接.
如何改进这一点以允许一次返回一行?
我使用SP,这不是SP vs代码隐藏"构建您的SQL命令"问题.我正在寻找一种处理许多小事务的后端应用程序的高吞吐量方法.我使用SQLDataReader进行大部分返回,因为转发仅适用于大多数情况.
我已经看到它做了很多种方式,并且我自己也使用了大部分方法.
定义和接受存储过程参数作为参数本身的方法,并使用cmd.Parameters.Add构建(使用或不指定DB值类型和/或长度)
将SP参数及其值组装到数组或散列表中,然后传递给一个更抽象的方法来解析集合,然后运行cmd.Parameters.Add
表示表的类,根据需要初始化类,设置表示表字段的公共属性,以及调用Save,Load等方法
我确信还有其他我见过但现在也想不到的.我对所有建议持开放态度.
基于StackOverflow站点周围的链接(下面的参考资料),我提出了这个代码块来执行从我的C#应用程序到MySQL数据库的查询.
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
dbConn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT version() as Version";
using (IDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
Console.WriteLine("Database Version: " + reader.GetString(reader.GetOrdinal("Version")));
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,每次我要进行一组查询时,我必须构建这个庞大的代码块,因为我不会(也不应该)在应用程序的生命周期中保持连接打开.
是否有更有效的方法来构建支持结构(嵌套usings,打开连接等),而是传递我的连接字符串和我想要运行的查询并获得结果?
参考问题:
这是我看过的三个.还有一些,但我的Google-fu现在无法重新启动它们.所有这些都为如何执行单个查询提供了答案.我想执行单独的业务逻辑查询 - 其中一些重复 - 并且不想重复不需要的代码.
我尝试过:基于nawfal的评论,我有以下两种方法:
private MySqlDataReader RunSqlQuery(string query)
{
Dictionary<string, string> queryParms = new Dictionary<string, string>();
MySqlDataReader QueryResult = RunSqlQuery(query, queryParms);
return QueryResult;
}
private MySqlDataReader …Run Code Online (Sandbox Code Playgroud) 如果我使用类似的东西:
using (OdbcConnection conn = new OdbcConnection(....))
{
conn.open();
my commands and sql, etc.
}
Run Code Online (Sandbox Code Playgroud)
我是否必须做一个conn.close(); 或者使用声明是否阻止我做最后一次通话?它是否处理了使用块中的所有内容?例如,如果我将其他对象称为不相关的,那么它也会自动消耗吗?
谢谢.在阅读有关在微软网站上使用后,我不清楚.我想确保我没有任何内存泄漏.
c# ×5
.net ×2
asp.net ×2
datareader ×2
.net-2.0 ×1
ado.net ×1
database ×1
generic-list ×1
mysql ×1
sql-server ×1
using ×1
vb.net ×1