-2

WinFormsクライアントからWCFサービスおよびSQL ServerテーブルにExcelファイルを渡す方法は?

誰でもガイダンス、コード、またはアドバイスを提供できますか?

  1. Excel ファイルをパラメーターとして受け取る WCF サービス コントラクトと実装
  2. コントラクトの実装では、その Excel ファイルを SQL Server の varbinary(MAX) 列に挿入する必要があります。
4

2 に答える 2

2
  • これは、質問の WCF 部分に対処する投稿です。
  • サーバーにファイルを取得したら、FileHelpers.netを使用してそのファイルをオブジェクトに解析できます。

あなたの要件が何を言っているかは気にしません。ExcelドキュメントをSQLサーバーのvarbinary(max)列に挿入しないでください。要件には、「Excel ドキュメントをアップロードし、そのコンテンツをデータベースに挿入する。ただし、元の Excel ファイルをデータベース内のデータに関連付ける必要があるため、プロセスが失敗したという主張を否定し、検証メカニズムを備える必要があります。 ."

  • EXCEL_IMPORT という別のテーブルを作成する
    か、次の列を多かれ少なかれ含むものを作成します

列の説明については、そこに配置した拡張プロパティを確認してください

create table EXCEL_IMPORT 
(
     ImportID   int identity(1,1) NOT NULL CONSTRAINT [PK_EXCEL_IMPORT] PRIMARY KEY,
     FileName_Incoming  varchar(max),
     FilePath_Internal  varchar(max),
     FileName_Internal  varchar(max),
     FileRowCount   int NOT NULL CONSTRAINT [CK_EXCEL_IMPORT_FileRowCount] CHECK  (FileRowCount >= 0),
     ImportDate datetime NOT NULL CONSTRAINT [DF_EXCEL_IMPORT_ImportDate] DEFAULT(getdate())
)

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The location on the client computer i.e. C:\Users\jimmy\Desktop\iHeartExcel.xls' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'EXCEL_IMPORT', @level2type=N'COLUMN',@level2name=N'FileName_Incoming'
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The folder on your fileshare the file is in (this is incase you decide to change the fileshare name)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'EXCEL_IMPORT', @level2type=N'COLUMN',@level2name=N'FilePath_Internal'
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The unique filename that you decided on in the fileshare i.e. 2012_04_20_11_34_59_0_71f452e7-7cac-4afe-b145-6b7557f34263.xls' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'EXCEL_IMPORT', @level2type=N'COLUMN',@level2name=N'FileName_Internal'
  • 次に、Excel ファイルをファイル共有上の場所にコピーし、一意のファイル名を作成するプロセスを記述します。この時点で、ファイル、ファイル自体、およびファイルを配置する場所に関するすべての情報を表すオブジェクトが得られます。
  • Excel スプレッドシートの列を模倣するテーブルを作成し、その末尾に ImportID を追加します。このテーブルは、上記で定義した Excel_import テーブルと ID プライマリ キーを参照します。
  • その後、指定されたリレーションシップでオブジェクトをデータベースに挿入するプロセスを記述します。これは、現在の設定によって異なります。
  • 最後に、ディスク上のファイルを指すインポート テーブルの行を参照するすべての Excel データを含むキー付きテーブルが必要です。

その他の考え

  • テーブル内のExcelデータを変更できないようにすることを考えます。計算された形式で別のテーブルにコピーします。データの量が原因でこれがうまくいかない場合もありますが、ここで行っていることは、元のソースに戻るデータの証明可能なチェーンを構築することであり、場合によっては、汚染されていないファイルのコピーと sql のコピーを用意することが理にかなっています。
  • 最初の応答は、「しかし、すべての Excel ファイルが異なります!」です。その場合は、ディスク上のファイルを指すインポート テーブルを作成するだけです (異なると想定されている場合)。それらが同じであると思われる場合は、さらにエラーチェックが必要です。
  • データベース内にバイナリ ファイルを保存すると、結果が生じます。つまり、バックアップ サイズとその sql は実際にはこれらの種類の列にインデックスを付けることができません。そのテーブルのトラバーサルも、ファイルを挿入するたびに遅くなり、一般的なルールとして、それは望ましくありません。(ディスク上のファイルに対して行うことは、バイナリ ファイルに対して行うことより多かれ少なかれ行うことはできません)
  • 共有のファイル名に日付を付加した GUID を使用します。いずれにせよ、これらのファイルを探し回ることはありません。日付で検索する必要がある場合は、ファイル名を使用できます。これにより、他のプロセスもここに書き込む必要がある場合に備えて、名前がグローバルに一意になります。
  • これがあなたの求めたものではないことはわかっていますが、私は以前にこの道をたどり、ひどい結果をもたらしました。上記の方法で何百万ものファイルをインポートしましたが、プロセスに大きな問題はありませんでした。
  • 要件が実現不可能な場合は、声を上げてください。同じことをより安価に、またはより簡単に行う代替案を提案してください (テスト可能/スケーラブルなどの言葉を使用してください)。
于 2012-04-20T15:58:39.780 に答える
0

そこの専門家がこれを改善できると確信していますが、ここに基本があります...

サーバー上

1a. インターフェイスに新しい OperationContract を追加します (例: IService.cs)。

[OperationContract]
string UploadBinaryFile(byte[] aByteArray);

1b. コントラクト実装 (Service.cs など) の SQL Server テーブルに挿入します。

public string UploadBinaryFile(byte[] aByteArray)
{
    try
    {
        SqlConnection conn = new SqlConnection();
        conn.ConnectionString = MyConnectionString; // from saved connection string
        conn.Open();
        using (SqlCommand cmd = new SqlCommand("INSERT INTO MyTestTable(BinaryFile) VALUES (@binaryfile)", conn))
        {
            cmd.Parameters.Add("@binaryfile", SqlDbType.VarBinary, -1).Value = aByteArray;
            cmd.ExecuteNonQuery();
        }

        return "1"; // to me, this indicates success
    }
    catch (Exception ex)
    {
        return "0: " + ex.Message; // return an error indicator + ex.message
    }
}

クライアント上

2a. OpenFileDialog コンポーネントを使用して、ほとんどの Windows アプリケーションで使用される標準のダイアログ ボックスを使用して、ファイル システム上のファイルを参照します。

if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
    txtUploadFilePath.Text = openFileDialog1.FileName;
}

2b. ファイルの内容をバイト配列にロードします

var byte[] BinaryFile = System.IO.File.ReadAllBytes(txtUploadFilePath.Text);

2c。バイト配列を渡して、WCF コントラクトを呼び出します

string UploadResponse = client.UploadBinaryFile(BinaryFile);

それは働いています... YAY :-)

于 2012-04-23T14:17:17.953 に答える