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

发布于 2024-12-20 23:23:11 字数 587 浏览 0 评论 0原文

我正在尝试读取存储在 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。代码有什么问题吗?

I'm trying to read the image file stored in a MongoDB, to do that I have following code in my ASP.net MVC 3 projects

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;
    }
}

When queried the database I can see the content exist for the ProfilePicture file, but when here in the C# project the content length is 0. Is there anything wrong in the code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黑白记忆 2024-12-27 23:23:11

看起来好像您在 User 中嵌入了 GridFile ,像

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

That 这样的东西是行不通的;至少,不是通过默认行为。 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 的单元测试

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

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

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

It looks as if you were embedding GridFile in User, something like

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

That won't work; at least, not through default behavior. GridFiles must be treated as first-class citizens, and they must be stored and retrieved using a GridFileCollection object:

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

You can find more working sample code in NoRM's unit tests.

The reason is that, while GridFile is basically a class like any other, the storage scheme for grid files is very different. While 'normal' objects are serialized in-place, and one document always corresponds to one object, this is not true for GridFile.

Because files can be much larger than the maximum document size in MongoDB, they'll be split up into chunks. Thus, when you store a GridFile, the driver will have to store the grid file and a number of chunks. By default, chunks are 256kB in size, so the number of chunks will depend on the data size. The default collection names are fs.files and fs.chunks.

All this logic resides in the GridFileCollection class, so it won't be executed if you're simply storing an embedded GridFile object instead of calling the Files() extension explicitly to retrieve the GridFileCollection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文