使用NoRM驱动程序从MongoDB读取文件内容

时间:2011-12-12 17:26:52

标签: c# mongodb norm gridfs

我正在尝试读取存储在MongoDB中的图像文件,为此我在ASP.net MVC 3项目中有以下代码

public FileContentResult ProfileImage(ObjectId id)
{

    using (var db = new MongoSession<User>())
    {
        var user = db.Queryable.Where(p => p.Id == id).FirstOrDefault();
        if (user != null && user.ProfilePicture != null)
        {   
            return File(user.ProfilePicture.Content.ToArray(), user.ProfilePicture.ContentType);
        }

        return null;
    }
}

查询数据库时,我可以看到ProfilePicture文件的内容,但是在C#项目中,内容长度为0。代码有什么问题吗?

1 个答案:

答案 0 :(得分:1)

看起来好像是在GridFile中嵌入了User,类似于

class User 
{ 
    public GridFile ProfilePicture {get; set;}
}

这不起作用;至少,不是通过默认行为。 GridFile必须被视为一等公民,并且必须使用GridFileCollection对象存储和检索它们:

var gridFS = conn.Database.Files();
var file = new GridFile();
// initialize file
gridFS.Save(file);
// query
var file2 = gridFS.FindOne(new { _id = file.Id });
// now, you can iterate file2.Content

您可以在NoRM's unit tests中找到更多可用的示例代码。

原因是,虽然GridFile基本上是一个类,但网格文件的存储方案非常不同。虽然“普通”对象就地序列化,并且一个文档始终对应于一个对象,但GridFile不是这样。

因为文件可能比MongoDB中的最大文档大小大得多,所以它们将被分成chunks。因此,当您存储GridFile时,驱动程序必须存储网格文件多个块。默认情况下,块大小为256kB,因此块的数量取决于数据大小。默认集合名称为fs.filesfs.chunks

所有这些逻辑都驻留在GridFileCollection类中,因此如果您只是存储嵌入的GridFile对象而不是显式调用Files()扩展来检索它,则不会执行该逻辑GridFileCollection