【问题标题】:How can I store a file in SQL database?如何将文件存储在 SQL 数据库中?
【发布时间】:2019-01-23 04:32:46
【问题描述】:

我正在使用以下代码从 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; }
    }

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

【问题讨论】:

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


【解决方案1】:

如果您使用的是 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();
    }

【讨论】:

    【解决方案2】:

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

    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"
    

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

    【讨论】:

    • 为什么 OP 不使用已经在他的程序中使用的技术,为什么当 OP 想要在数据库中拥有一个文件时会有一个文件?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    相关资源
    最近更新 更多