C# - 什么是一些高性能的最佳实践/提示ADO.NET高性能、提示、NET、ADO

2023-09-03 08:47:02 作者:薄荷味

我决定不使用ORM,并打算直接使用ADO.NET为我的项目。我知道,我知道它会需要更长的时间来编程,但我只是想页以高速加载,即使在高峰时间。

I decided not to use an orm and going to use straight ADO.NET for my project. I know I know its gonna take longer to program but I just want pages to load at high speeds even at peak time.

推荐答案

一个错误我看到重复了一遍又一遍:

One error I see repeated over and over again:

实例化和建立的一切(的DbConnection,的DbCommand,DbParameters),一个是在紧密循环反复调用方法中。

Instantiating and setting up everything (DbConnection, DbCommand, DbParameters) inside a method which is called repeatedly in a tight loop.

大多数时候,你可以重构中的局部变量的类成员实例他们只有一次,只保留更新DbParameters的方法内的时间。

Most of the time you can refactor those local variables as class members instantiating them only once and keeping only the updates to DbParameters inside the method.

更新,包括样品code要求的意见

免责声明: 这是展示有关移动重复性的圈外点的唯一目的的快速组装的样品。 其他更好的做法不一定落实。

Disclaimer: This is a quick assembled sample for the sole intent of demonstrating the point about moving repetitive stuff out of the loop. Other better practices aren't necessarily implemented.


        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; }
    }

在此先执行,每一件事情在每次调用方法时设置了:


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();
            }
        }
    }
}

现在,我们将设置到对象的建设留出循环:


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();
    }
}