La conversion implicite de VARCHAR en VARBINARY n'est pas autorisée

Je suis coincé avec un problème. Je développe une application ASP.net MVC qui gère les téléchargements de files vers une database. Ce n'est pas un si gros problème. Mais chaque fois que j'exécute mon SQL-Command, il me dit que je dois d'abord convertir en VARBINARY.

Ce problème est très demandé ici et sur Internet, mais je n'arrive toujours pas à le faire fonctionner.

C'est ce que j'ai

La table SQL:

DocID INT IDENTITY(1,1) NOT NULL, DocName VARCHAR(512) NOT NULL, DocData VARBINARY(max) NOT NULL, ContentType NVARCHAR(100) NOT NULL, ContentLength BIGINT NOT NULL, InsertionDate DATETIME NOT NULL DEFAULT GETDATE(), CONSTRAINT PK_DOC_STORE PRIMARY KEY NONCLUSTERED (DocID) 

Lisez le file sur un octet [] avec BinaryReader.

 var reader = new BinaryReader(file.InputStream); var data = reader.ReadBytes(file.ContentLength); 

Et le code INSERT INTO C #:

 sqlConnection.Open(); var sqlCommand = new SqlCommand ( "INSERT INTO DocStore VALUES ('@DocumentName', '@DocumentData', '@DocumentType', '@DocumentSize', '@DocumentDate')" , sqlConnection ); sqlCommand.Parameters.AddWithValue("@DocumentName", file.FileName); sqlCommand.Parameters.AddWithValue("@DocumentData", data); sqlCommand.Parameters.AddWithValue("@DocumentType", file.ContentType); sqlCommand.Parameters.AddWithValue("@DocumentSize", file.ContentLength); sqlCommand.Parameters.AddWithValue("@DocumentDate", DateTime.Now); var success = sqlCommand.ExecuteNonQuery(); sqlConnection.Close(); 

Quel est le problème ici? Je ne peux pas voir le problème .. Le byte [] ne devrait-il pas fonctionner dans une string de command paramétrée comme celle-ci pour la partie VARBINARY?

Solution

Au lieu de

 var sqlCommand = new SqlCommand ( "INSERT INTO DocStore VALUES ('@DocumentName', '@DocumentData', '@DocumentType', '@DocumentSize', '@DocumentDate')" , sqlConnection ); 

j'utiliserais

 var sqlCommand = new SqlCommand ( "INSERT INTO DocStore VALUES (@DocumentName, @DocumentData, @DocumentType, @DocumentSize, @DocumentDate)" , sqlConnection ); 

Pourquoi ?

Parce que la string "INSERT INTO ... '@DocumentData' ... " contient une instruction T-SQL. Dans T-SQL, les guillemets simples ( 'bla' ) sont utilisés pour délimiter le début et la fin de la string et aussi, dans certains cas, peuvent être utilisés pour les délimiteurs de colonne. Donc '@DocumentData' représente une constante string / VARCHAR du sharepoint vue de SQL Server. Dans ce cas, il essaie d'effectuer une conversion implicite des valeurs VARCHAR ( '@D...' ) en VARBINARY (type de données de la DocData DocData, la première colonne est ignorée car elle a la propriété IDENTITY ). Mais selon entrez la description de l'image ici entre VARCHAR et VARBINARY sont autorisés que des conversions explicites.

Remarque: en tant que meilleure pratique, je définirais explicitement la list des colonnes cibles pour l'instruction INSERT .

Vous mettez des guillemets autour des noms de parameters, ce qui les rendra littéraux.

Aussi, je suggère de spécifier les colonnes dans l'instruction d' insert . Si vous ne spécifiez pas les colonnes à insert, il prend la définition exacte de votre table (à l'exclusion du champ ID car il est incrémenté automatiquement). Il est possible de casser votre requête si vous insérez un champ entre les deux.

 INSERT INTO DocStore (DocName, DocData, ContentType, ContentLength, InsertionDate) VALUES (@DocumentName, @DocumentData, @DocumentType, @DocumentSize, @DocumentDate)