C# - ADO.NET的一些高性能最佳实践/技巧是什么?

use*_*433 15 .net c# performance ado.net

我决定不使用orm并将直接使用ADO.NET作为我的项目.我知道我知道它需要更长的时间来编程,但我只是希望页面即使在高峰时也能以高速加载.

Alf*_*ers 10

我一遍又一遍地看到一个错误:

在紧密循环中重复调用的方法中实例化和设置所有内容(DbConnection,DbCommand,DbParameters).

大多数情况下,您可以将这些局部变量重构为类成员,只将它们实例化一次,并仅保留方法内的DbParameters更新.


更新以包含评论中要求的示例代码

免责声明:这是一个快速组装的样本,其唯一目的是展示关于将重复的东西移出循环的观点.其他更好的做法未必实施.


        public static void Show() {
            List people = new List();

            //Everything is done inside the loop
            PersonDal personDal = new PersonDal();
            foreach (Person person in people) {
                personDal.Insert(person);
            }

            //Things are setup once outside the loop.
            using (DbConnection connection = SqlClientFactory.Instance.CreateConnection()) {
                // setup the connection
                BetterPersonDal betterPersonDal = new BetterPersonDal(connection);
                connection.Open();
                foreach (Person person in people) {
                    betterPersonDal.Insert(person);
                }
            }
        }
    }

    class Person {
        public int Id { get; set; }
        public string Name { get; set; }
    }

Run Code Online (Sandbox Code Playgroud)

在第一个实现中,每次调用方法时都会设置每个东西:


class PersonDal {
    public int Insert(Person person) {
        DbProviderFactory factory = SqlClientFactory.Instance;

        using (DbConnection connection = factory.CreateConnection()) {
            connection.Open();

            connection.ConnectionString = "Whatever";

            using (DbCommand command = connection.CreateCommand()) {
                command.CommandText = "Whatever";
                command.CommandType = CommandType.StoredProcedure;

                DbParameter id = command.CreateParameter();
                id.ParameterName = "@Id";
                id.DbType = DbType.Int32;
                id.Value = person.Id;

                DbParameter name = command.CreateParameter();
                name.ParameterName = "@Name";
                name.DbType = DbType.String;
                name.Size = 50;
                name.Value = person.Name;

                command.Parameters.AddRange(new DbParameter[] { id, name });

                return (int)command.ExecuteScalar();
            }
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

现在我们将设置移动到对象构造,使其离开循环:


class BetterPersonDal {
    private DbProviderFactory factory;
    private DbConnection connection;
    private DbCommand command;
    private DbParameter id;
    private DbParameter name;

    public BetterPersonDal(DbConnection connection) {
        this.command = connection.CreateCommand();
        this.command.CommandText = "Whatever";
        this.command.CommandType = CommandType.StoredProcedure;

        this.id = command.CreateParameter();
        this.id.ParameterName = "@Id";
        this.id.DbType = DbType.Int32;

        this.name = command.CreateParameter();
        this.name.ParameterName = "@Name";
        this.name.DbType = DbType.String;
        this.name.Size = 50;

        this.command.Parameters.AddRange(new DbParameter[] { id, name });
    }

    public int Insert(Person person) {
        this.id.Value = person.Id;
        this.name.Value = person.Name;

        return (int)command.ExecuteScalar();
    }
}

Run Code Online (Sandbox Code Playgroud)


M4N*_*M4N 5

看看提高 .NET 应用程序性能和可伸缩性一书(在 MSDN 中免费在线提供)。有一整章是关于提高 ADO.NET 性能的。