繁体   English   中英

数据表性能以及如何从数据表释放内存?

[英]Data table performance and how releasing memory from a data table?

这是我的课:

public class DbHelper

{

public static DataTable Select(string query, object[,] parameters)
{
    DataTable dt = new DataTable();
    SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["DBConnection"].ToString());
    SqlCommand com = new SqlCommand();
    com.Connection = cn;
    com.CommandText = query;
    for (int i = 0; i < parameters.Length/2; i++)
        com.Parameters.AddWithValue(parameters[i, 0].ToString(), parameters[i, 1]);
    try
    {
        cn.Open();
        dt.Load(com.ExecuteReader());
    }
    catch
    {
    }
    finally
    {
        com.Dispose();
        cn.Close();
        cn.Dispose();
    }
    return dt;
}

}

我正在使用此类从数据库中进行选择,如下所示:

    public static string NewsListTitle(int count, int categoryId, string domainName)
{
    StringBuilder cnt = new StringBuilder();
    DataTable dt = DbHelper.Select("SELECT top " + count + " ..... ");
    foreach (DataRow i in dt.Rows)
    {
        cnt.Append("<li><a target=\"_blank\" href=\"http://" + domainName + "/news/" + i["NewsID"] + "\"\">" + i["Title"] + "</a></li>");
    }
    return cnt.ToString();
}

DataTable类型是一种将数据存储在内存中的强大方法。 我认为这是从数据库中选择的最佳方法,但是我的问题是DateTable的内存使用情况! 这里有什么错误或更好的方法吗?

谢谢

DataTable类型是一种将数据存储在内存中的强大方法。

如果功能强大,则意味着内存膨胀,缓慢但非常灵活-在90%的情况下绝对不需要...。

我认为这是从数据库中选择的最佳方法

你完全正确。 如果编写报告生成器,则在编程时不知道数据的结构。 在任何其他情况下(例如95%的情况),这都是一个不错的“为竞争而努力”的理由,可让您被解雇。

但是我的问题是DateTable的内存使用率!

是。 因为众所周知,强大的通用机制是内存和性能的消耗。 现在有多好?

使用ORM从SQL语句中获取对象的枚举(即真实对象,而不是通用状态存储)。 一切-哎呀,听说过Entity Framework吗?

然后,永远不要在内存中实现数据。

最重要的是,学习使用数据进行编程的绝对基础:要求尽可能少的数据。 例如,如果您认为自己现在遇到问题-浏览器将非常喜欢1亿个条目的列表。 最好使用分页,以减少内存消耗,因为它永远不会要求超过一百或两百行。

并且,请了解2014年使用daa的基础知识-数据集,MS早在几年前就开始将其淘汰,但架构并没有太大改变。 世界向前发展。

正如我在上面的评论中所说。 我将更加关注代码中隐含的双循环。 解决这两个问题的IEnumerable方法是使用DataReaderIEnumerable方法

在您的DBHelper类中添加此

public static IEnumerable<IDataReader> Reader(string query, object[,] parameters)
{
    using(SqlConnection cn = new SqlConnection(.....))
    using(SqlCommand com = new SqlCommand(query, cn))
    {
        for (int i = 0; i < parameters.Length/2; i++)
            com.Parameters.AddWithValue(parameters[i, 0].ToString(), parameters[i, 1]);

        cn.Open();
        using(SqlDataReader r = com.ExecuteReader())
        {
            while(r.Read())
                yield return r;
        }
    }
}

现在,您可以创建输出而无需创建DataTable并仅在查询的结果集上循环一次。

public static string NewsListTitle(int count, int categoryId, string domainName)
{
    StringBuilder cnt = new StringBuilder();
    foreach(IDataRecord rc in DbHelper.Reader("......", ....);
    {
         cnt.Append(@"<li><a target=\"_blank\" href=\"http://" + domainName + "/news/" +
               rc.GetInt32(rc.GetOrdinal("NewsID")).ToString() + "\"\">" + 
               rc.GetString(rc.GetOrdinal("Title")) + "</a></li>");
    }
    return cnt.ToString();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM