我正在尝试读取存储在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
。代码有什么问题吗?
答案 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.files
和fs.chunks
。
所有这些逻辑都驻留在GridFileCollection
类中,因此如果您只是存储嵌入的GridFile
对象而不是显式调用Files()
扩展来检索它,则不会执行该逻辑GridFileCollection
。