增强我的代码的指南

发布于 2024-08-04 09:04:11 字数 1952 浏览 6 评论 0原文

该程序会将表 1 中的所有记录复制到表 2 中,并写入文本文件。复制完所有记录后,记录将被删除,使 table1 为空,然后再添加新记录。我喜欢增强我的代码,例如:

  1. 像插入代码来验证记录是否为空,如果复制文件时遇到问题,或者如果是 EOF,我应该做什么?
  2. 这段代码位于 form_load() 中并在 win 表单应用程序中运行,如果我运行程序 exe,我不知道要出现的表单怎么办?我想让这个程序就像在后面的Windows上运行一样。只会出现错误或成功的消息框?
  3. 任何解决方案、指导或参考方面的帮助都非常非常感谢。

先感谢您!


//create connection
 SqlConnection sqlConnection1 =
   new SqlConnection("Data Source=.\SQLEXPRESS;Database=F:\Test2.mdf;Integrated Security=True;User Instance=True");
//command insert into queries
  SqlCommand cmdCopy = new SqlCommand();
  cmdCopy.CommandType = System.Data.CommandType.Text;
  cmdCopy.CommandText = "INSERT INTO tblSend (ip, msg, date) SELECT ip, msg, date FROM tblOutbox";
  cmdCopy.Connection = sqlConnection1;
//insert into text file
  SqlCommand cmd = new SqlCommand();
  cmd.CommandType = CommandType.Text;
  cmd.CommandText = "SELECT * FROM tblOutbox";
  cmd.Connection = sqlConnection1;
  sqlConnection1.Open();
  StreamWriter tw = File.AppendText("c:\INMS.txt");
  SqlDataReader reader = cmd.ExecuteReader();
  tw.WriteLine("id, ip address, message, datetime");
  while (reader.Read())
  {
   tw.Write(reader["id"].ToString());
   tw.Write(", " + reader["ip"].ToString());
   tw.Write(", " + reader["msg"].ToString());
   tw.WriteLine(", " + reader["date"].ToString());
  }
  tw.WriteLine("Report Generate at : " + DateTime.Now);
  tw.WriteLine("---------------------------------");
  tw.Close();
  reader.Close();
//command delete
  String strDel = "DELETE tblOutbox";
  SqlCommand cmdDel = new SqlCommand(strDel, sqlConnection1);
//sqlConnection1.Open(); //open con
cmdCopy.ExecuteScalar(); cmd.ExecuteNonQuery(); //execute insert query cmdDel.ExecuteScalar();//execute delete query
sqlConnection1.Close(); //close con //*****************************************************
} catch (System.Exception excep) { MessageBox.Show(excep.Message); }

This program will copy all records inside the table 1 into table 2 and also write into a text file. After it finishes copied all the records, the records will be delete make the table1 empty before new record is added. i like to enhance my code for example :

  1. like inserting code to verify if records empty or not, if got problem in copying the file, or if it is EOF, what should i do??
  2. This code was in form_load() and running in win form application, what if, if i run the program exe, i dont what the form to be appeared? i want to make this program like it was running on windows behind. Only error or successful messagebox will appeared?
  3. Any help in solution, guidance or reference are very very thankful.

Thank you in advance!


//create connection
 SqlConnection sqlConnection1 =
   new SqlConnection("Data Source=.\SQLEXPRESS;Database=F:\Test2.mdf;Integrated Security=True;User Instance=True");
//command insert into queries
  SqlCommand cmdCopy = new SqlCommand();
  cmdCopy.CommandType = System.Data.CommandType.Text;
  cmdCopy.CommandText = "INSERT INTO tblSend (ip, msg, date) SELECT ip, msg, date FROM tblOutbox";
  cmdCopy.Connection = sqlConnection1;
//insert into text file
  SqlCommand cmd = new SqlCommand();
  cmd.CommandType = CommandType.Text;
  cmd.CommandText = "SELECT * FROM tblOutbox";
  cmd.Connection = sqlConnection1;
  sqlConnection1.Open();
  StreamWriter tw = File.AppendText("c:\INMS.txt");
  SqlDataReader reader = cmd.ExecuteReader();
  tw.WriteLine("id, ip address, message, datetime");
  while (reader.Read())
  {
   tw.Write(reader["id"].ToString());
   tw.Write(", " + reader["ip"].ToString());
   tw.Write(", " + reader["msg"].ToString());
   tw.WriteLine(", " + reader["date"].ToString());
  }
  tw.WriteLine("Report Generate at : " + DateTime.Now);
  tw.WriteLine("---------------------------------");
  tw.Close();
  reader.Close();
//command delete
  String strDel = "DELETE tblOutbox";
  SqlCommand cmdDel = new SqlCommand(strDel, sqlConnection1);
//sqlConnection1.Open(); //open con
cmdCopy.ExecuteScalar(); cmd.ExecuteNonQuery(); //execute insert query cmdDel.ExecuteScalar();//execute delete query
sqlConnection1.Close(); //close con //*****************************************************
} catch (System.Exception excep) { MessageBox.Show(excep.Message); }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

猫腻 2024-08-11 09:04:11

一些建议:

  • 将其从表单中移出。业务逻辑和数据访问不属于表单(View)。将其移至单独的类中。
  • 将 MessageBox 代码保留在表单中。这就是显示逻辑。整个try..catch可以移出方法;只需让方法抛出异常即可。并且不要捕获 System.Exception - 捕获您期望的数据库异常。
  • 我同意 Ty 对 IDisposable 和 using 语句的评论。
  • 阅读提取方法单一责任原则。此方法执行很多操作,而且很长。打破它。
  • 移出一些字符串硬编码。如果您的连接字符串或文件路径发生变化怎么办?为什么不将它们放入配置文件中(或者至少使用一些常量)?

无论如何,对于初学者来说。 :)

A few suggestions:

  • Move it out of the form. Business logic and data access does not belong in the form (View). Move it to a separate class.
  • Keep the MessageBox code in the form. That's display logic. The entire try..catch can be moved out of the method; just have the method throw exceptions. And don't catch System.Exception - catch the database one(s) you expect.
  • I echo Ty's comments on IDisposable and using statements.
  • Read up on Extract Method and the Single Responsibility Principle. This method does a lot, and it's long. Break it up.
  • Move some of the string hardcodes out. What if your connection string or file paths change? Why not put those in a configuration file (or at least use some constants)?

For starters, anyway. :)

风月客 2024-08-11 09:04:11

这肯定是一些代码,如果您关心的话,我肯定可以推荐很多东西来改进它。

我要做的第一件事是阅读 IDisposable 然后我将重写该 DataReader 如下。

using(StreamWriter tw = File.AppendText("c:\INMS.txt"))
{
    using(SqlDataReader reader = cmd.ExecuteReader())
    {
      tw.WriteLine("id, ip_add, message, datetime");
      while (reader.Read())
      {
         tw.Write(reader["id"].ToString());
         tw.Write(", " + reader["ip_add"].ToString());
         tw.Write(", " + reader["message"].ToString());
         tw.WriteLine(", " + reader["datetime"].ToString());
      }
      tw.WriteLine(DateTime.Now);
      tw.WriteLine("---------------------------------");
   }
}

然后在捕获后,添加以下内容并删除千钧一发。

finally
{
   sqlConnection1.Dispose(); //close con
}

That sure is some code and I sure could recommend a lot of things to improve it if you care.

First thing I would do is read up on IDisposable then I would re-write that DataReader as following.

using(StreamWriter tw = File.AppendText("c:\INMS.txt"))
{
    using(SqlDataReader reader = cmd.ExecuteReader())
    {
      tw.WriteLine("id, ip_add, message, datetime");
      while (reader.Read())
      {
         tw.Write(reader["id"].ToString());
         tw.Write(", " + reader["ip_add"].ToString());
         tw.Write(", " + reader["message"].ToString());
         tw.WriteLine(", " + reader["datetime"].ToString());
      }
      tw.WriteLine(DateTime.Now);
      tw.WriteLine("---------------------------------");
   }
}

Then after your catch, put the following and remove the close call.

finally
{
   sqlConnection1.Dispose(); //close con
}
淡淡の花香 2024-08-11 09:04:11

除了已经给出的一些其他答案之外,您可能还需要考虑使用事务保护数据操作。

我假设您不希望以下任何操作部分完成:

  cmdCopy.ExecuteScalar();
  cmd.ExecuteNonQuery(); //execute insert query
  cmdDel.ExecuteScalar();//execute delete query

如果您正在处理许多行,您可能希望批量更新,但这是一个完全不同的问题。

In addition to some of the other answers already given, you might also want to consider protecting the data operation with a Transaction.

I assume that you don't want any of the following operation to partially complete:

  cmdCopy.ExecuteScalar();
  cmd.ExecuteNonQuery(); //execute insert query
  cmdDel.ExecuteScalar();//execute delete query

If you are processing MANY rows you might want to batch your updates but that is a whole different issue.

落花随流水 2024-08-11 09:04:11

首先,感谢您尝试提高自己的技能并愿意像这样发布您的代码。我相信成为一名更好的程序员的第一步就是要有这种态度。

这是一个可以回答您的一些问题的实现。
我已将一些旧代码提取到方法中,并将一些职责转移到它们自己的类中。

免责声明:

  • 虽然代码已编译,但我没有针对数据库运行它,因此我可能错过了一些小事情。
  • 我不得不在不知道确切要求的情况下停止某些重构,并且仍然尝试保持一些概念简单。

using System;
using System.Configuration;
using System.Data.SqlClient;
using System.IO;

// Program.cs
static class Program
{
    [STAThread]
    static void Main()
    {
        try
        {
            MailArchiver.Run();
            Console.WriteLine("Application completed successfully");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Unexpected error occurred:");
            Console.WriteLine(ex.ToString());
        }

    }
}

// Reads new messages from DB, save it to a report file 
// and then clears the table
public static class MailArchiver
{

    public static void Run()
    {
        // Might be a good idea to a datetime suffix 
        ReportWriter.WriteFile(@"c:\INMS.txt");
        CopyAndClearMessages();
    }

    private static void CopyAndClearMessages()
    {
        SqlConnection cn = DbConnectionFactory.CreateConnection();
        cn.Open();

        try
        {
            SqlTransaction tx = cn.BeginTransaction();

            try
            {
                CopyMessages(cn, tx);
                DeleteMessages(cn, tx);
                tx.Commit();
            }
            catch
            {
                tx.Rollback();
                throw;
            }
        }
        finally
        {
            cn.Close();
        }
    }

    private static void DeleteMessages(SqlConnection cn, SqlTransaction tx)
    {
        var sql = "DELETE FROM tblOutbox";
        var cmd = new SqlCommand(sql, cn, tx);
        cmd.CommandTimeout = 60 * 2;  // timeout 2 minutes 
        cmd.ExecuteNonQuery();
    }

    private static void CopyMessages(SqlConnection cn, SqlTransaction tx)
    {
        var sql = "INSERT INTO tblSend (ip, msg, date) SELECT ip, msg, date FROM tblOutbox";
        var cmd = new SqlCommand(sql, cn, tx);
        cmd.CommandTimeout = 60 * 2;  // timeout 2 minutes 
        cmd.ExecuteNonQuery();
    }
}

// Provides database connections to the rest of the app.
public static class DbConnectionFactory
{
    public static SqlConnection CreateConnection()
    {
        // Retrieve connection string from app.config
        string connectionString = ConfigurationManager.ConnectionStrings["MailDatabase"].ConnectionString;
        var cn = new SqlConnection(connectionString);

        return cn;
    }
}

// Writes all the data in tblOutbox to a CSV file
public static class ReportWriter
{
    private static SqlDataReader GetData()
    {
        SqlConnection cn = DbConnectionFactory.CreateConnection();
        cn.Open();

        try
        {
            var cmd = new SqlCommand();
            cmd.CommandText = "SELECT * FROM tblOutbox";
            cmd.Connection = cn;

            return cmd.ExecuteReader();
        }
        finally
        {
            cn.Close();
        }
    }

    public static void WriteFile(string filename)
    {
        if (File.Exists(filename))
        {
            // This might be serious, we may overwrite data from the previous run.
            // 1. You might want to throw your own custom exception here, should want to handle this
            //    condition higher up.
            // 2. The logic added here is not the best and added for demonstration purposes only.
            throw new Exception(String.Format("The file [{0}] already exists, move the file and try again"));
        }
        var tw = new StreamWriter(filename);

        try
        {
            // Adds header record that describes the file contents
            tw.WriteLine("id,ip address,message,datetime");

            using (SqlDataReader reader = GetData())
            {
                while (reader.Read())
                {
                    var id = reader["id"].ToString();
                    var ip = reader["ip"].ToString();

                    //msg might contain commas, surround value with double quotes
                    var msg = reader["msg"].ToString();
                    var date = reader["data"].ToString();

                    if (IfValidRecord(id, ip, msg, msg, date))
                    {
                        tw.WriteLine(string.Format("{0},{1},{2},{3}", id, ip, msg, date));
                    }
                }

                tw.WriteLine("Report generated at : " + DateTime.Now);
                tw.WriteLine("--------------------------------------");
            }

        }
        finally
        {
            tw.Close();
        }

    }

    private static bool IfValidRecord(string id, string ip, string msg, string msg_4, string date)
    {
        // this answers your question on how to handle validation per record.
        // Add required logic here
        return true;
    }
}

Firstly kudos to you for trying to improve your skill and being open to publish your code like this. I believe that is the first step to being a better programmer, is to have this type of attitude.

Here is an implementation that answers some of your questions.
I have extracted some of the old code into methods and also moved some of the responsibilities to their own classes.

Disclaimer:

  • Although the code compiles I didn't run it against a database, therefore there might be a couple of small things I missed.
  • I had to stop short on certain refactorings not knowing the exact requirements and also to still try and keep some of the concepts simple.

.

using System;
using System.Configuration;
using System.Data.SqlClient;
using System.IO;

// Program.cs
static class Program
{
    [STAThread]
    static void Main()
    {
        try
        {
            MailArchiver.Run();
            Console.WriteLine("Application completed successfully");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Unexpected error occurred:");
            Console.WriteLine(ex.ToString());
        }

    }
}

// Reads new messages from DB, save it to a report file 
// and then clears the table
public static class MailArchiver
{

    public static void Run()
    {
        // Might be a good idea to a datetime suffix 
        ReportWriter.WriteFile(@"c:\INMS.txt");
        CopyAndClearMessages();
    }

    private static void CopyAndClearMessages()
    {
        SqlConnection cn = DbConnectionFactory.CreateConnection();
        cn.Open();

        try
        {
            SqlTransaction tx = cn.BeginTransaction();

            try
            {
                CopyMessages(cn, tx);
                DeleteMessages(cn, tx);
                tx.Commit();
            }
            catch
            {
                tx.Rollback();
                throw;
            }
        }
        finally
        {
            cn.Close();
        }
    }

    private static void DeleteMessages(SqlConnection cn, SqlTransaction tx)
    {
        var sql = "DELETE FROM tblOutbox";
        var cmd = new SqlCommand(sql, cn, tx);
        cmd.CommandTimeout = 60 * 2;  // timeout 2 minutes 
        cmd.ExecuteNonQuery();
    }

    private static void CopyMessages(SqlConnection cn, SqlTransaction tx)
    {
        var sql = "INSERT INTO tblSend (ip, msg, date) SELECT ip, msg, date FROM tblOutbox";
        var cmd = new SqlCommand(sql, cn, tx);
        cmd.CommandTimeout = 60 * 2;  // timeout 2 minutes 
        cmd.ExecuteNonQuery();
    }
}

// Provides database connections to the rest of the app.
public static class DbConnectionFactory
{
    public static SqlConnection CreateConnection()
    {
        // Retrieve connection string from app.config
        string connectionString = ConfigurationManager.ConnectionStrings["MailDatabase"].ConnectionString;
        var cn = new SqlConnection(connectionString);

        return cn;
    }
}

// Writes all the data in tblOutbox to a CSV file
public static class ReportWriter
{
    private static SqlDataReader GetData()
    {
        SqlConnection cn = DbConnectionFactory.CreateConnection();
        cn.Open();

        try
        {
            var cmd = new SqlCommand();
            cmd.CommandText = "SELECT * FROM tblOutbox";
            cmd.Connection = cn;

            return cmd.ExecuteReader();
        }
        finally
        {
            cn.Close();
        }
    }

    public static void WriteFile(string filename)
    {
        if (File.Exists(filename))
        {
            // This might be serious, we may overwrite data from the previous run.
            // 1. You might want to throw your own custom exception here, should want to handle this
            //    condition higher up.
            // 2. The logic added here is not the best and added for demonstration purposes only.
            throw new Exception(String.Format("The file [{0}] already exists, move the file and try again"));
        }
        var tw = new StreamWriter(filename);

        try
        {
            // Adds header record that describes the file contents
            tw.WriteLine("id,ip address,message,datetime");

            using (SqlDataReader reader = GetData())
            {
                while (reader.Read())
                {
                    var id = reader["id"].ToString();
                    var ip = reader["ip"].ToString();

                    //msg might contain commas, surround value with double quotes
                    var msg = reader["msg"].ToString();
                    var date = reader["data"].ToString();

                    if (IfValidRecord(id, ip, msg, msg, date))
                    {
                        tw.WriteLine(string.Format("{0},{1},{2},{3}", id, ip, msg, date));
                    }
                }

                tw.WriteLine("Report generated at : " + DateTime.Now);
                tw.WriteLine("--------------------------------------");
            }

        }
        finally
        {
            tw.Close();
        }

    }

    private static bool IfValidRecord(string id, string ip, string msg, string msg_4, string date)
    {
        // this answers your question on how to handle validation per record.
        // Add required logic here
        return true;
    }
}
澜川若宁 2024-08-11 09:04:11
  1. 使用 SELECT 查询查找非空行(您似乎能够解决 EOF 问题)。
  2. form_load 事件中,程序参数使表单不可见。
  3. 为什么不使用 INSERT INTO (然后删除)?
  1. Use a SELECT query to find the non-empty rows (you seem to get along with the EOF issue).
  2. On form_load event make the form invisible by program arguments.
  3. Why not to use INSERT INTO (and then DELETE)?
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文