2017-05-23 13 views
0

winformアプリケーションをSQL ServerにアーカイブするためのC#でアプリケーションを作成しています。これまではのファイルを選択してのファイルを選択し、選択した文書のパスをリストボックスに保存しました。ここでは、コードは次のとおりです。データベースに複数のファイルを挿入する#

public void btnLoad_Click(object sender, EventArgs e) 
    { 
     OpenFileDialog dlg = new OpenFileDialog(); 
     dlg.Multiselect = true; 
     dlg.Filter = "All files (*.*)|*.*"; 

     DialogResult dlgRes = dlg.ShowDialog(); 
     if (dlgRes == DialogResult.OK) 
     { 

      foreach (String file in dlg.FileNames) 
      { 

       listBox1.Items.Add(file); 
      } 
     } 

    } 

私は今、何をしたいかは、データベースへOpenFileDialogに選択されているすべての文書を挿入することです。 EDIT ファイルをデータベースに挿入するコードです。

byte[] ReadFile(string sPath) 
    { 
     //Initialize byte array with a null value initially. 
     byte[] data = null; 

     //Use FileInfo object to get file size. 
     FileInfo fInfo = new FileInfo(sPath); 
     long numBytes = fInfo.Length; 

     //Open FileStream to read file 
     FileStream fStream = new FileStream(sPath, FileMode.Open, FileAccess.Read); 

     //Use BinaryReader to read file stream into byte array. 
     BinaryReader br = new BinaryReader(fStream); 

     //When you use BinaryReader, you need to supply number of bytes to read from file. 
     //In this case we want to read entire file. So supplying total number of bytes. 
     data = br.ReadBytes((int)numBytes); 

     //Close BinaryReader 
     br.Close(); 

     //Close FileStream 
     fStream.Close(); 

     return data; 
    } 

    private void btnDocAdd_Click(object sender, EventArgs e) 
    { 

     var myOtherList = listBox1.Items.Cast<String>().ToList(); 

     foreach (var f in myOtherList) 
     { 

      byte[] FileData = ReadFile(f); 
      string path = Path.GetFileName(f); 
      //Set insert query 

      string qry = @"Insert into FilesStore (Linja, Magazina, Arkiva, OriginalPath,FileData,Lloji, Data,NrProt, EmriDok,Perdoruesi) values(@linja,@magazina,@arkiva,@OriginalPath, @FileData, @lloji, @Data,@nrprot, @emr,@perdoru)"; 

      //Initialize SqlCommand object for insert. 
      SqlCommand SqlCom = new SqlCommand(qry, con); 
      DateTime dt = DateTime.Now;    // Use current time 
      string format = "dd/MM/yyyy HH:mm:ss"; // modify the format depending upon input required in the column in database 
                 // string insert = @" insert into Table(DateTime Column) values ('" + dt.ToString(format) + "')"; 
                 //We are passing Original File Path and File byte data as sql parameters. 

      SqlCom.Parameters.Add(new SqlParameter("@linja", (object)cbLinja.Text)); 
      SqlCom.Parameters.Add(new SqlParameter("@magazina", (object)cbDokMagazina.Text)); 
      SqlCom.Parameters.Add(new SqlParameter("@arkiva", (object)cbArkiv.Text)); 
      SqlCom.Parameters.Add(new SqlParameter("@OriginalPath", (object)f)); 
      SqlCom.Parameters.Add(new SqlParameter("@FileData", (object)FileData)); 
      SqlCom.Parameters.Add(new SqlParameter("@lloji", (object)cbLloji.Text)); 
      SqlCom.Parameters.Add(new SqlParameter("@Data", (object)dt.ToString(format))); 
      SqlCom.Parameters.Add(new SqlParameter("@nrprot", (object)txtDocProt.Text)); 
      SqlCom.Parameters.Add(new SqlParameter("@emr", (object)Path.GetFileNameWithoutExtension(path))); 
      SqlCom.Parameters.Add(new SqlParameter("@perdoru", (object)lblPerd.Text)); 

      con.Open(); 

      SqlCom.ExecuteNonQuery(); 

      con.Close(); 

ドキュメントを1つずつ追加するとうまく動作します。しかし、複数のドキュメントを追加しようとすると、1つのドキュメントをx回追加するだけです(x =リストボックスの項目数)

+1

にリストボックスを使用するバージョン(まだ開いていないダイアログ)でありますあなたのSQLコードを表示し、何も動作していないことを示します – BugFinder

+1

'dlg。FileNames'はすでに文書のリスト(ファイルの内容ではなくファイル名)を含んでいます。それはあなたが投稿したコードの意図から明らかです。データベースに何かを保存する方法を尋ねる場合は、データベースに追加する方法のコード例を示す必要があります。 – Flater

+0

デバッグ中の 'myOtherList'をチェックしましたか? –

答えて

-2

カンマ区切りの同じ列にすべてのパスをまとめて保存し、 DBから。

var DBValue = string.Join(",", listBox1.Items.Cast<String>().ToList()) 

をDBから取得するために:

var ListofAttachments= DBValue.Split(',').ToList<string>(); 
+0

yuk、これはちょうど乱雑な正規化されたデータになります。それぞれをリストする別々のテーブルを持つほうがずっと良いです。それからそれは照会可能です。 – ADyson

+0

...あなたのデータベースに照らされていない悪夢をデータベースに... – spender

+0

@ADyson 5つの異なるリストボックスから1,000を超える添付ファイルを追加しようとするとどうなりますか?別のテーブルに5000レコードを挿入する必要はありますか? –

0

次はopenDialogのを採用していないが、代わりに、私はシンプルなアプリ以下のフォルダ内のすべての画像を選択し、一緒全てのパスに参加する

デバッグフォルダは、もちろんハードコードされていますが、単にOpenDialogを使ってイメージファイルを取得するだけです。これをシミュレーションと考えてください。

フォームコード(ここではクラス内のメソッドを呼び出します)ここではファイルにデータを挿入し、画像を挿入すると新しい主キーも取得します。実際のアプリでは、変更されたリストを返します。ここではそうではありません。保存されたファイル情報へ

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.IO; 
using System.Linq; 
using System.Windows.Forms; 

namespace WindowsFormsApplication3 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      var location = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images"); 
      List<ImageItem> imageItemsList = (
       from file in Directory.GetFiles(location) 
       select new ImageItem 
       { 
         Name = Path.GetFileName(file), 
         Bytes = File.ReadAllBytes(file), 
         Description = "Inserted from code sample" 
        } 
       ).ToList(); 

      DatabaseImageOperations ops = new DatabaseImageOperations(); 
      ops.InsertImages(imageItemsList); 
     } 
    } 
} 

データ操作クラス

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Data.SqlClient; 

public class DatabaseImageOperations 
{ 
    private string databaseServer = @".\SQLEXPRESS"; 
    private string defaultCatalog = "ImageData1"; 
    private string _ConnectionString; 
    private string ConnectionString 
    { 
     get 
     { 
      return _ConnectionString; 
     } 
     set 
     { 
      _ConnectionString = value; 
     } 
    } 
    public DatabaseImageOperations() 
    { 
     _ConnectionString = $"Data Source={databaseServer};Initial Catalog={defaultCatalog};Integrated Security=True"; 
    } 
    public void InsertImages(List<ImageItem> Images) 
    { 
     using (SqlConnection cn = new SqlConnection { ConnectionString = ConnectionString }) 
     { 
      using (SqlCommand cmd = new SqlCommand { Connection = cn }) 
      { 
       cmd.CommandText = "INSERT INTO ImageData (ImageData, [Description]) " + 
            "VALUES (@img, @description);SELECT CAST(scope_identity() AS int);"; 

       cmd.Parameters.Add("@img", SqlDbType.Image); 
       cmd.Parameters.Add("@description", SqlDbType.Text); 

       cmd.Parameters.Add(new SqlParameter 
       { 
        ParameterName = "@new_identity", 
        SqlDbType = SqlDbType.Int, 
        Direction = ParameterDirection.Output 
       }); 

       cn.Open(); 

       foreach (ImageItem item in Images) 
       { 
        cmd.Parameters["@img"].Value = item.Bytes; 
        cmd.Parameters["@description"].Value = item.Description; 
        item.Id = Convert.ToInt32(cmd.ExecuteScalar()); 
       } 
      } 
     } 
    } 
} 

クラス。

public class ImageItem 
{ 
    public int Id { get; set; } 
    public byte[] Bytes { get; set; } 
    public string Description { get; set; } 
    public string Name { get; set; } 
} 

表構造

USE [ImageData1] 
CREATE TABLE [dbo].[ImageData](
    [ImageID] [int] IDENTITY(1,1) NOT NULL, 
    [ImageData] [image] NULL, 
    [Description] [nvarchar](max) NULL, 
CONSTRAINT [PK_ImageData] PRIMARY KEY CLUSTERED 
(
    [ImageID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

GO 

がうまくいけば、これはあなたの仕事に適応することができ、パターン賢明に役立ちます。 enter image description here

編集:ここ はその後

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.IO; 
using System.Linq; 
using System.Windows.Forms; 

namespace WindowsFormsApplication3 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      var location = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images"); 
      List<ImageItem> imageItemsList = (
       from file in Directory.GetFiles(location) 
       select new ImageItem 
       { 
         Name = Path.GetFileName(file), 
         Bytes = File.ReadAllBytes(file), 
         Description = "Inserted from code sample" 
        } 
       ).ToList(); 

      listBox1.DataSource = imageItemsList; 
      listBox1.DisplayMember = "Name"; 

     } 
     private void button2_Click(object sender, EventArgs e) 
     { 
      var imageItemsList = (List<ImageItem>)listBox1.DataSource; 
      DatabaseImageOperations ops = new DatabaseImageOperations(); 
      ops.InsertImages(ref imageItemsList); 
     } 
    } 
} 

小変更データクラス

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Data.SqlClient; 

public class DatabaseImageOperations 
{ 
    private string databaseServer = @"L-36007\SQLEXPRESS"; 
    private string defaultCatalog = "ImageData1"; 
    private string _ConnectionString; 
    private string ConnectionString 
    { 
     get 
     { 
      return _ConnectionString; 
     } 
     set 
     { 
      _ConnectionString = value; 
     } 
    } 
    public DatabaseImageOperations() 
    { 
     _ConnectionString = $"Data Source={databaseServer};Initial Catalog={defaultCatalog};Integrated Security=True"; 
    } 
    public void InsertImages(ref List<ImageItem> Images) 
    { 
     using (SqlConnection cn = new SqlConnection { ConnectionString = ConnectionString }) 
     { 
      using (SqlCommand cmd = new SqlCommand { Connection = cn }) 
      { 
       cmd.CommandText = "INSERT INTO ImageData (ImageData, [Description]) " + 
            "VALUES (@img, @description);SELECT CAST(scope_identity() AS int);"; 

       cmd.Parameters.Add("@img", SqlDbType.Image); 
       cmd.Parameters.Add("@description", SqlDbType.Text); 

       cmd.Parameters.Add(new SqlParameter 
       { 
        ParameterName = "@new_identity", 
        SqlDbType = SqlDbType.Int, 
        Direction = ParameterDirection.Output 
       }); 

       cn.Open(); 

       foreach (ImageItem item in Images) 
       { 
        cmd.Parameters["@img"].Value = item.Bytes; 
        cmd.Parameters["@description"].Value = item.Description; 
        item.Id = Convert.ToInt32(cmd.ExecuteScalar()); 
       } 
      } 
     } 
    } 
} 

enter image description here

関連する問題