There is a code (it is working), but I would like to know, can I simplify it somehow? Especially interested, can I somehow reduce the number of lines? Simply because of using using , exception blocks, etc., the code is stretched, readability is lost.

Please answer as clearly as possible for a newbie :)

 public partial class CreateAds : Form { public MainForm otherForm; string pathBase = Path.Combine(Application.StartupPath, "ads.db"); public CreateAds(MainForm form1) { InitializeComponent(); otherForm = form1; btCreate.Click += (sender, e) => { if (!File.Exists(pathBase)) { SQLiteConnection.CreateFile(pathBase); using (SQLiteConnection con = new SQLiteConnection(string.Format("Data Source={0};", pathBase))) { using (SQLiteCommand cmd = new SQLiteCommand("CREATE TABLE `base` (ID integer primary key, Name varchar, DateCreate varchar, DateEnd varchar, Mesto tinyint(5));", con)) { try { con.Open(); cmd.ExecuteNonQuery(); } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { con.Close(); } } } } using (SQLiteConnection con = new SQLiteConnection(string.Format("Data Source={0};", pathBase))) { try { con.Open(); string query = string.Format("INSERT INTO 'base' ('Name', 'DateCreate', 'DateEnd', 'Mesto') VALUES ('{0}', '{1}', '{2}', '{3}');", tbName.Text, tbDateCreate.Text, tbDateEnd.Text, tbMesto.Value); using (SQLiteCommand cmd = new SQLiteCommand(query, con)) { cmd.ExecuteNonQuery(); } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { con.Close(); } } otherForm.dgv.Rows.Add(tbName.Text, tbDateCreate.Text, tbDateEnd.Text, tbMesto.Value, "Удалить"); }; } } 

 public static async Task InsertBase(string Names, string DateCreates, string DateEnds, decimal Mestos) { string pathBase = Path.Combine(Application.StartupPath, "ads.db"); using (SQLiteConnection con = new SQLiteConnection(string.Format("Data Source={0};", pathBase))) { await con.OpenAsync(); string query = string.Format("INSERT INTO 'base' ('Name', 'DateCreate', 'DateEnd', 'Mesto') VALUES ('{0}', '{1}', '{2}', '{3}');", Names, DateCreates, DateEnds, Mestos); using (SQLiteCommand cmd = new SQLiteCommand(query, con)) { await cmd.ExecuteNonQueryAsync(); } } } 

  • one
    Lambda is done <= ~ 7 lines, and if it is not possible, then a method is made which is called from lambda. And why was it impossible to immediately subscribe to an event? Why make this? And about asynchrony, have you heard? - Bulson
  • one
    Using does not close the connection? - Vadim Prokopchuk
  • @Bulson, I did not think that so many lines will come out. About asynchrony heard .. can you specifically specify what is wrong? - Maxim
  • one
    @VadimProkopchuk, i.e., you mean, the connection is automatically closed when you exit the using block? - Maxim
  • 3
    Using using assumes that you do not need to prescribe Close , because class implements IDisposable - Bulson

1 answer 1

SQLiteConnection con should be made private field of the class, and frankly, work with the database should be carried out in a separate class Repository , completely rendered, away from the UI.

SQLite is a local database, in principle, the connection can be kept open throughout the entire program operation time. The program started, the connection was established, when closing the program we close the connection.

Create an interface with all the required methods: create, read, update, delete and use it as the type for the field through which you will work with the Repository class.

Methods in the Repository need to be made asynchronous, to do this, create ordinary synchronous methods, check how they work (test), and then do this:

 //предположим у нас есть синхронный метод public bool DeleteEntity(int id) {...} //делаем ему асинхронного брата public Task<bool> DeleteEntityAsync(int id) { return Task.Run<bool>(() => { return DeleteEntity(id); }); } 

Then in the right place we can call him like this.

 bool result = await _repository.DeleteEntityAsync(123); 
  • Thank! Is my code very bad compared to yours? (I attached it to the first post) - Maxim
  • one
    No need to create "asynchronous brothers". - andreycha
  • one
    The public methods of the repository are its API. And the UI (or other layer) is the client of this API. Therefore, let the client decide how to run the method. - andreycha
  • one
    @andreycha, thanks for bringing my attention to this issue. But in this particular case, the guy writes a small program, and he himself knows that he has a synchronous, and that is just an asynchronous wrapper. So I do not understand what the problem is? Whether he is a synchronous method will wrap in the UI in Task.Run (), or he will do it in advance in the repository, and thereby adds brevity to the UI code. Well, what's the criminal !? - Bulson
  • one
    The guy writes a small program and he knows where he has access to the database, and where is the interface, why does he need a repository? ;) The rules are first better learned, implemented, and only then learn to break. - andreycha