如何在SQL数据库中存储文件?

时间:2019-01-03 17:30:51

标签: c# asp.net-web-api

我正在使用以下代码从Angular获取文件:

 var httpPostedFile = HttpContext.Current.Request.Files["file"];

这是我的目录:

 string folderExists = (HttpContext.Current.Server.MapPath("~/abc"));

如何将文件保存到该文件夹​​中?

for (int i = 0; i < HttpContext.Current.Request.Files.Count; i++)
{
    var FileName = httpPostedFile.FileName;
    int fileSize = httpPostedFile.ContentLength;
    byte[] fileByteArray = new byte[fileSize];
    httpPostedFile.InputStream.Read(fileByteArray, 0, fileSize);

    string fileLocation = Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/uploads"), FileName);

    if (!Directory.Exists(HttpContext.Current.Server.MapPath("~/App_Data/uploads")))
        Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/App_Data/uploads"));

    httpPostedFile.SaveAs(fileLocation);
}

我将文件保存到文件夹中,但是我想将这些文件存储在SQL数据库中。

我的文件结构:

 public class FileTable
    {
        [Key]
        public int Id { get; set; }
        public byte[] FileData { get; set; }
        public string FileName { get; set; }
    }

如何将文件存储在数据库中?

2 个答案:

答案 0 :(得分:0)

您可以使用存储过程存储文件:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[spStoreBinaryFiles]
    @FILE_PATH VARCHAR(MAX)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @FILE_LENGTH BIGINT
    DECLARE @FILE_DATA VARBINARY(MAX)
    DECLARE @FILE_NAME VARCHAR(100)
    DECLARE @DOCUMENT_NAME VARCHAR(100) 
    DECLARE @DOCUMENT_NATURE VARCHAR(5)  

    DECLARE @VAL1 VARCHAR(100)
    DECLARE @VAL2 VARCHAR(100)

    DECLARE curDOCUMENTS CURSOR FOR 
         SELECT *  
         FROM dbo.SPLIT ( ';', @FILE_PATH)

    OPEN curDOCUMENTS

    FETCH NEXT FROM curDOCUMENTS INTO @VAL1, @VAL2

    WHILE @@FETCH_STATUS = 0
    BEGIN
        IF OBJECT_ID('#ORStable') IS NULL 
        BEGIN
            CREATE TABLE #ORStable _
            (Length BIGINT, vDocument VARBINARY(MAX))

            DECLARE @SQL_QUERY NVARCHAR(1000)

            SET @SQL_QUERY = 'INSERT INTO #ORStable
                                SELECT len(bulkcolumn), *
                                FROM OPENROWSET(BULK '''+@VAL2+''', _
                SINGLE_BLOB) AS BinaryData'

            EXEC SP_executesql @SQL_QUERY
        END

        EXEC dbo.spGetDocumentNature @VAL2, @DOCUMENT_NATURE OUTPUT
        EXEC dbo.spGetDocumentName @VAL2, @DOCUMENT_NAME OUTPUT

        SELECT TOP 1 @FILE_LENGTH = Length, @FILE_DATA = vDocument 
        FROM #ORStable

       INSERT INTO dbo.tblBinaryFiles ([File], [Path], [Ext], [Size],[Binary])
       VALUES (@DOCUMENT_NAME, @VAL2, @DOCUMENT_NATURE, @FILE_LENGTH, @FILE_DATA)

       DROP TABLE dbo.#ORStable

       FETCH NEXT FROM curDOCUMENTS INTO @VAL1, @VAL2
   END

   CLOSE curDOCUMENTS
   DEALLOCATE curDOCUMENTS 
END

现在您可以像这样调用此存储过程:

       DECLARE @SQL_QUERY     NVARCHAR(1000)

        SET @SQL_QUERY= '
        INSERT INTO #ORStable
        SELECT len(bulkcolumn), *
        FROM OPENROWSET(BULK '''+@VAL2+''', _
                SINGLE_BLOB) AS BinaryData'
        exec SP_executesql @SQL_QUERY

此处的变量VAL2包含单个文件路径信息。

示例

VAL2 = "\\192.168.1.1\myFiles\yourfile.pdf"

VAL2 = "C:\yourFilesFolder\yourfile.pdf"

注意:如果您使用任何网络路径或活动路径,请确认您的文件夹具有读写权限

答案 1 :(得分:0)

如果您使用的是Entity Framework Core,并且已将迁移推送到表,则可以创建一个新的FileTable类,并将字节数组附加到它(如果它已存在于数据库中)。您只需将其添加到FileData属性中,然后将其保存在数据库中。如果尚未创建数据库,则只需确保FileData的列的类型为varbinary(max)。

一个例子是:

public void AttachFile(byte[] byteArray, int objectID)
        {
            FileTable currentFileTable = new FileTable();
            currentFileTable = _yourcontext.yourtable.Where(e => e.ID == objectID).FirstOrDefault();
            currentFileTable.FileData = byteArray;
            _yourcontext.yourtable.Update(currentFileTable);
            _yourcontext.SaveChanges();
}

如果您已经在数据库中有一个对象并且知道ID是什么,那么这将起作用。如果它是一个新对象,则只需执行以下操作:

public void AttachFile(byte[] byteArray)
            {
                FileTable currentFileTable = new FileTable();                
                currentFileTable.FileData = byteArray;
                //Populate your other properties
                _yourcontext.yourtable.Add(currentFileTable);
                _yourcontext.SaveChanges();
    }