Insertion de données dans SQL Server 2014 en C # (Visual 2015) à l'aide de classs et de procédures stockées

J'ai un problème lors de l'insertion de données dans ma database SQL Server. J'utilise une class appelée livre et dans ma design de formulaire lorsque je veux insert des données, je reçois une erreur.

class Book { private ssortingng _bookname; private int _bookcode; private int _numberofpages; private ssortingng _author; private ssortingng _publicationname; private ssortingng _genre; private int _publishyear; private ssortingng _language; SqlConnection _sqlcon = new SqlConnection(); public Book(SqlConnection sqlcon) { _sqlcon = sqlcon; } public ssortingng bookname { get { return _bookname; } set { _bookname = value; } } public int bookcode { get { return _bookcode; } set { _bookcode = value; } } public int numberofpages { get { return _numberofpages; } set { _numberofpages = value; } } public ssortingng author { get { return _author; } set { _author = value; } } public ssortingng publicationname { get { return _publicationname; } set { _publicationname = value; } } public ssortingng genre { get { return _genre; } set { _genre = value; } } public int publishyear { get { return _publishyear; } set { _publishyear = value; } } public ssortingng language { get { return _language; } set { _language = value; } } public void SaveBook() { SqlConnection _sqlcon = new SqlConnection(); SqlCommand com = new SqlCommand(); com.CommandType = CommandType.StoredProcedure; com.Connection = _sqlcon; com.CommandText = "PROC_BOOK1"; com.Parameters.Add("@nameofbook", SqlDbType.VarChar).Value = bookname; com.Parameters.Add("@codeofbook", SqlDbType.Int).Value = bookcode; com.Parameters.Add("@npages", SqlDbType.Int).Value = numberofpages; com.Parameters.Add("@bookauthor", SqlDbType.VarChar).Value = author; com.Parameters.Add("@publicationname", SqlDbType.VarChar).Value = publicationname; com.Parameters.Add("@bookgenre", SqlDbType.VarChar).Value = genre; com.Parameters.Add("@pyear", SqlDbType.Int).Value = publishyear; com.Parameters.Add("@booklanguage", SqlDbType.VarChar).Value = language; com.ExecuteNonQuery(); 

et voici mon button d'insertion:

 public partial class Form1 : Form { private SqlConnection _sqlcon = new SqlConnection(); private Book _book1; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void btnsabt_Click(object sender, EventArgs e) { _book1 = new Book(_sqlcon); _book1.bookname = txtbookname.Text; _book1.bookcode = Convert.ToInt32(txtbookcode.Text); _book1.numberofpages = Convert.ToInt32(txtnumberofpages.Text); _book1.author = txtauthor.Text; _book1.publicationname = txtpublication.Text; _book1.genre = txtgenre.Text; _book1.publishyear = Convert.ToInt32(txtpublishyear.Text); _book1.language = txtlanguage.Text; _book1.SaveBook(); MessageBox.Show("saved succesfully"); } 

Voici l'instantané de l'erreur:

entrez la description de l'image ici

Votre problème est dans la façon dont vous avez conçu ce model de livre.

Vous forcez les users à utiliser un constructor qui reçoit une SqlConnection puis (il s'agit probablement d'une erreur) vous créez une nouvelle instance de SqlConnection (sans connectionsortingng) dans la méthode SaveBook.
Vous souhaitez probablement utiliser la SqlConnection passée dans le constructor et vous vous attendez à ce que les clients de cette class l'initialisent avec un paramètre approprié pour la string de connection et l'ouvrent.

Donc, si vous voulez vraiment que vos clients fournissent la connection, alors l'initialiser avec la string de connection et l'ouvrir AVANT d'initier l'instance de livre dans la méthode de clic. Bien sûr, supprimez la ligne qui crée une nouvelle connection dans la méthode SaveBook.

 public void SaveBook() { // This line defines a local variable with the same name of the global one // It hides the global, if you expect your client to provide the connection // then remove the line SqlConnection _sqlcon = new SqlConnection(); .... 

Je trouve ce design pas très sage. C'est un nid de frelons qui commence déjà à vous piquer de toutes les manières possibles.

Le model (Book) ne doit pas se préoccuper de la façon dont il est sauvegardé dans son stockage final (ou chargé à partir de), qu'il s'agisse d'une table de database, d'un file XML, d'un service distant ou de tout ce que vous devez faire à l'avenir.

Au lieu de cela, une class dédiée pour gérer les transactions de database doit avoir tout le code pour save et récupérer datatables du livre de la table de database (dans ce cas)

Je l'aurais conçu avec une class nommée BookDB

 public class BookDB { public bool Save(Book obj) { using(SqlConnection con = RepositoryUtility.GetConnection()) { // here code to check and save the object .... } } public Book LoadByKey(int bookID) { using(SqlConnection con = RepositoryUtility.GetConnection()) { Book aBook = new Book(); // here goes the code to load a book from the db using the primarykey .... return aBook } } ... other db methods based .... } 

Comme l'erreur l'indique, vous n'ouvrez pas la connection. Vous devriez avoir une string de connection et faire quelque chose comme ça avec cet object de connection:

 using (SqlConnection sqlConnection = new SqlConnection(ConnectionSsortingng)) { sqlConnection.Open(); ...do stuff } 

Ajoutez ceci dans votre méthode SaveBook.

 SqlConnection _sqlcon = new SqlConnection(); _sqlcon.ConnectionSsortingng = "DATA SOURCE = <sql server instance name>; INITIAL CATALOG = <database name>; INTEGRATED SECURITY = SSPI"; _sqlcon.Open(); 

Vous devez ouvrir l'object _sqlCon et affecter une string de connection à votre server de database SQL. J'espère que cela t'aides!

L'erreur est explicite, vous devez ouvrir votre connection, sauf si la connection est fermée, vous obtiendrez cette erreur

  SqlConnection _sqlcon = new SqlConnection(); _sqlcon.Open(); . .//other codes . _sqlcon.Close();//at the end close your connection 

Il suffit d'éditer ceci:

 com.connection.open(); com.ExecuteNonQuery(); com.connection.close(); 

Vous devez ouvrir la connection avant de pouvoir exécuter vos requêtes sur la database, puis fermez-la une fois que vous avez terminé.