关于c#:使用实体框架将文件保存在数据库中

Save files in database with entity framework

我有一个基于实体框架和Microsoft SQL Server 2008构建的ASP.NET MVC解决方案。我需要创建一个允许我的用户上传文件的函数。

我想要的是:

  • 使用实体框架在数据库中存储文件的解决方案
  • 一种通过某种哈希/校验和检测并阻止同一文件两次上载的解决方案。
  • 数据库/表设计提示

在实体模型中,将BLOB数据库列映射到byte[]属性。将上载文件的内容分配给实体对象的该属性,并在ObjectContext中保存更改。

要计算哈希,可以使用MD5CryptoServiceProvider


在SQL Server 2008数据库中存储文件的"正确"方法是使用文件流数据类型。我不知道实体框架支持这一点,但是您当然可以尝试看看会发生什么。

也就是说,大多数情况下,当人们这样做时,他们不会将文件存储在数据库中。这样做意味着您需要通过ASP.NET和数据库服务器来提供一个可以直接从Web服务器提供服务的文件。它还可能使数据库和站点的备份图片有些复杂。因此,当我们将文件上载到MVC/实体框架时,我们只在数据库中存储对文件位置的引用,并将文件本身存储在其他地方。

显然,哪种策略适合您,很大程度上取决于您的应用程序的细节。


以下是我在播客中的做法:

1
2
3
ID     Title         Path                    Summary              UploadDate
---    -----        --------              ----------------        -----------
1     TestPodcast   /Podcasts/ep1.mp3      A test podcast         2010-02-12

path存储了对播客物理位置的引用。我使用了ScottHanselman的一篇文章来处理文件上传部分。


基于@thomas's answer的一个工作示例(仅用于上传文件,因为此示例在Google中排名第一):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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;
            }
        }