【问题标题】:More efficient way of run SQL query运行 SQL 查询的更有效方式
【发布时间】:2015-12-08 04:56:18
【问题描述】:

我正在尝试查看是否有更短的编写代码来运行 SQL 查询的方法。我之前使用的是实体框架,但它的加载速度似乎比使用 SQL 命令慢。任何建议都会很棒。提前致谢!

这是我的 SQL 命令的代码:

        string query = "Select Count(*) From Employee Where Email = @Email And Password = @Password";
        string queryEmployeeId = "Select EmployeeId From Employee Where Email =@Email and Password = @Password";
        string queryAdmin = "Select Admin From Employee Where Email =@Email and Password = @Password";
        string queryFirstName = "Select FirstName From Employee Where Email =@Email and Password = @Password";
        int result = 0;
        int employeeId = 0;
        int admin = 0;
        string employeeFirstName;

        using (SqlConnection connection = new SqlConnection(@"Data Source=198.71.227.2;Initial Catalog=TaskManager;Integrated Security=False;User ID=;Password=;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False"))
        {
            using (SqlCommand command = new SqlCommand(query, connection))
            {
                command.Parameters.AddWithValue("@Email", txtEmail.Text);
                command.Parameters.AddWithValue("@Password", txtPassword.Text);
                connection.Open();
                result = (int)command.ExecuteScalar();
            }

            using (SqlCommand command = new SqlCommand(queryEmployeeId, connection))
            {
                command.Parameters.AddWithValue("@Email", txtEmail.Text);
                command.Parameters.AddWithValue("@Password", txtPassword.Text);
                employeeId = (int)command.ExecuteScalar();
            }

            using (SqlCommand command = new SqlCommand(queryAdmin, connection))
            {
                command.Parameters.AddWithValue("@Email", txtEmail.Text);
                command.Parameters.AddWithValue("@Password", txtPassword.Text);
                admin = (int)command.ExecuteScalar();
            }

            using (SqlCommand command = new SqlCommand(queryFirstName, connection))
            {
                command.Parameters.AddWithValue("@Email", txtEmail.Text);
                command.Parameters.AddWithValue("@Password", txtPassword.Text);
                employeeFirstName = (string)command.ExecuteScalar();
            }
        }

        if (result > 0)
        {
            Session["EmployeeId"] = employeeId;
            Session["Admin"] = admin;
            Session["EmployeeFirstName"] = employeeFirstName;
            Response.Redirect("~/MyJobSheet.aspx");
        }

最初,这是我的实体框架代码:

        string username = txtEmail.Text;
        string password = txtPassword.Text;

        using (TaskManagerEntities myEntities = new TaskManagerEntities())
        {
            var employee = (from a in myEntities.Employees
                            where a.Email == username && a.Password == password
                            select new { a.EmployeeId, a.Admin, a.Email, a.Password, a.FirstName }).SingleOrDefault();

            if (employee != null)
            {
                Session["EmployeeId"] = employee.EmployeeId;
                Session["Admin"] = employee.Admin;
                Session["EmployeeFirstName"] = employee.FirstName;
                Response.Redirect("~/MyJobSheet.aspx");
            }

【问题讨论】:

  • 为什么你在同一个查询上有一个Count(),你后来明确假设它只包含一行(例如employeeFirstName = (string)command.ExecuteScalar();)?另外,为什么不直接运行SELECT EmployeeId, Admin, FirstName from ...
  • 我会先查看由 EF 生成的 SQL,看看它是否由于某种原因创建了不必要的大 SQL
  • 我遵循了我看到的代码,但我想我不需要 count()。我正在考虑按照您所说的方式编写 SELECT 语句,但是如何将它们保存在每个会话变量中?我还编辑了代码,我没有复制它的一部分。 @Rob
  • 如果result <= 0 则不需要运行其余的查询,对吗?您也许可以通过使用异步代码来并行化此操作,尽管在 Web 窗体中正确执行此操作有点棘手。
  • 为什么不编写一个存储过程,它返回一个包含以下列 EmployeeID、Admin、EmployeeFirstname 的表。此外,可以在存储过程本身中检查员工是否存在(如果存在而不是 count(*),对用户更好)。通过这样做,将只有一个数据库调用而不是 4 个。此外,正如史蒂夫提到的,请确保电子邮件列已编入索引。

标签: c# sql asp.net .net entity-framework-6


【解决方案1】:

编写一个存储过程,它返回一个包含以下列 EmployeeID、Admin、EmployeeFirstname 的表。此外,还可以在存储过程本身中检查员工是否存在(如果存在而不是 count(*),对用户来说更好) .

通过这样做,将只有一个数据库调用而不是 4 个。此外,正如史蒂夫所说,确保电子邮件列已编入索引

【讨论】:

    【解决方案2】:

    ADO.NET 总是比任何 ORM 更有效,因为它更“低级”,当您执行只读查询时,您可以做的是关闭实体框架提供的一些功能。例如,您使用AsNoTracking() 获取您的实体,但没有必要让您的上下文跟踪它们。

    var blogs2 = context.Blogs 
                        .Where(b => b.Name.Contains(".NET")) 
                        .AsNoTracking() 
    

    或者您可以使用Dapper,为每个实体创建一个只读查询的存储库,它使用 ADO.Net 方法,但比纯 ADO.Net 工作效率更高

    【讨论】:

      猜你喜欢
      • 2013-08-31
      • 1970-01-01
      • 2014-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-10
      • 1970-01-01
      • 2022-01-13
      相关资源
      最近更新 更多