使用实体框架将文件保存在数据库中

18

我有一个使用Entity Framework和Microsoft SQL Server 2008构建的ASP.NET MVC解决方案。 我需要创建一个允许用户上传文件的功能。

我想要的是:

  • 一个使用Entity Framework将文件存储在数据库中的解决方案
  • 一个可以通过某种哈希/校验和检测并防止重复上传相同文件的解决方案
  • 关于数据库/表设计的提示
4个回答

46
在实体模型中,将BLOB数据库列映射到byte[]属性。将上传文件的内容分配给实体对象的该属性,并在ObjectContext中保存更改。
要计算哈希值,您可以使用MD5CryptoServiceProvider类。

15
那个回答有什么问题吗?能否至少给一个打负分的理由?这是我在 SO 上真正讨厌的一件事:人们会毫无解释地进行负分投票... 它太没有意义了。 - Thomas Levesque
7
不太清楚......但因为你的努力给你加个+1 :) - Craig Stuntz
4
这件事的不好之处在于,如果使用字节数组而不是流来处理大文件,就有可能会耗尽您的内存(RAM)。 - jocull

9
在 SQL Server 2008 数据库中存储文件的“正确”方法是使用 FILESTREAM 数据类型。我不知道 Entity Framework 是否支持该数据类型,但你可以尝试并查看结果。
话虽如此,大多数情况下人们并不会将文件存储在数据库中。这样做意味着你需要通过 ASP.NET 和数据库服务器来提供文件,而实际上你可以直接从 Web 服务器提供文件。这也可能会使你的数据库和站点备份变得更加复杂。因此,当我们上传文件到 MVC/Entity Framework 时,我们仅在数据库中存储文件位置的引用,并将文件本身存储在其他地方。
显然,哪种策略适合你取决于你的应用程序的具体情况。

1
链接已失效。 - Emaro

5
这是我为播客处理的方法:
ID     标题         路径                    摘要              上传日期
---    -----        --------              ----------------        -----------
1     TestPodcast   /Podcasts/ep1.mp3      一个测试播客         2010-02-12

路径 存储了播客物理位置的引用。我使用了 Scott Hanselman 在ASP.NET MVC文件上传中的基础案例研究,包括测试和模拟 来处理文件上传部分。

这对于小型应用程序可能还可以,但是假设有备份要求和文件随时间变化,您将无法返回到特定的时间点。 - ozz
1
@Ozz 你说得太对了;但这并不适用于随时间变化的文件。我希望一旦发布了一个播客,你不会回头去覆盖那个播客。 - George Stocker

0
一个工作示例(仅适用于文件上传,因为这是谷歌搜索中排名第一的)基于@Thomas的答案:
public void AddDocument(HttpPostedFileBase file)
        {
            try
            {                
                    using (TransactionScope scope = new TransactionScope())
                    {
                        try
                        {
                            using (var ctx = new Entities())
                            {

                            EntityDoc doc = new EntityDoc(); //The document table 

                            doc.DocumentFileName = file.FileName; //The file Name

                            using (var reader = new System.IO.BinaryReader(file.InputStream))
                            {
                                doc.DocumentFile = reader.ReadBytes(file.ContentLength); // the Byte [] Field
                            }
                            ctx.EntityDocs.Add(doc);


                                ctx.SaveChanges();
                                scope.Complete();
                            }
                        }
                        catch (Exception ex)
                        {                          
                            throw ex;
                        }
                    }

            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接