【问题标题】:Upload multiple pictures to SQL Server database using Entity Framework in ASP.NET MVC使用 ASP.NET MVC 中的实体框架将多张图片上传到 SQL Server 数据库
【发布时间】:2022-08-16 14:55:20
【问题描述】:

我一直在尝试使用实体框架将多张图片上传到 SQL Server 数据库。

我之前已经成功将一张图片上传到数据库,但我需要一次上传多张图片。

我尝试在 DtoModel 中将图片作为ICollection<IFormFile> Pic 拍摄,并将它们转换为主要模型中的 byte[] 以将它们存储在数据库中,但它没有用,我只是将一张图片存储在我拥有的许多数据库中上传。

主要型号:

public class property
{
    [Key]
    public int Id { get; set; }
   
    public string Name { get; set; }

    [Required(ErrorMessage = \"Photo is required.\")]
    public byte[] Pic { get; set; }

    public string PicFromat { get; set; }
}

模型:

public class dtoprop
{
    public string Name { get; set; }

    public ICollection<IFormFile> Pic { get; set; }

    public string PicFromat { get; set; }

}

控制器:

private readonly ApplicationDbContext _context;
private new List<string> _allowedExtenstions = new List<string> { \".jpg\", \".png\" }; 
private long _maxAllowedPosterSize = 1048576;

public propertiesController(ApplicationDbContext context)
{
    _context = context;
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create( dtoprop model)
{
        if (!ModelState.IsValid)
        {
            return View( model);
        }

        if(!_allowedExtenstions.Contains(Path.GetExtension(model.Pics.FileName.ToLower())))
        {
            ModelState.AddModelError(\"Pic\", \"Only .PNG, .JPG images are allowed!\");
    
            return View(model);
        }
    
        if (model.Pics.Length > _maxAllowedPosterSize)
        {
            ModelState.AddModelError(\"Pic\", \"Poster cannot be more than 1 MB!\");
            return View(model);
        }

        using var dataStream = new MemoryStream();

        await model.Pics.CopyToAsync(dataStream);

   using var dataStream = new MemoryStream();
            byte[] conv = null;


            if (model.Pic != null )
            {
                // Loop thru each selected file
                foreach (IFormFile photo in model.Pic)
                {
                    await photo.CopyToAsync(dataStream);

                     conv = dataStream.ToArray();

                }
            }


        var pic = new property
        {
            Name = model.Name,
             Pic = conv,
            PicFromat = model.PicFromat
        };

        _context.Properties.Add(pic);
        _context.SaveChanges();

        return RedirectToAction(\"Index\");
}

那么,我是否需要创建一个与主模型具有一对多关系的新图像模型?或者有更好的方法可以实现这种方法而不将图像存储在 wwwroot 文件夹中?

  • 您似乎将所有文件字节附加到一个流中。您需要为每个IFormFile 创建一个_context.Properties.Add(pic);....
  • @JeremyLakeman 你能回答你的建议吗?
  • 您是否有理由将二进制文件存储在您的数据库表中而不是某处的大容量存储中?在RDBMS中存储图像会引入瓶颈并引入其他问题(因此为什么MS最近添加了FILESTREAM,但它几乎不是灵丹妙药),所以通常最好不是将文件存储在数据库中。
  • 看起来您需要在循环内添加,还要确保每次都为字节数组实例化变量,而不是像建议的那样追加。探索的另一个选项是直接使用 InputStream,它应该已经有一个可以使用的字节数组列表。我认为他们曾经将其称为 InputStream,但这已在 .net 核心中进行了更改。
  • @Dai我知道,我想知道这种方法

标签: c# asp.net asp.net-mvc asp.net-core asp.net-web-api


【解决方案1】:

重写您的控制器代码块,如下所示:

if (model.Pic != null )
{
    // Loop thru each selected file
    foreach (IFormFile photo in model.Pic)
    {
        var dataStream = new MemoryStream();
        await photo.CopyToAsync(dataStream);

        byte[] conv = dataStream.ToArray();

        var pic = new property()
        {
            Name = model.Name,
            Pic = conv,
            PicFromat = model.PicFromat
        };

        _context.Properties.Add(pic);
    }
}

_context.SaveChanges();

【讨论】:

  • 感谢您的回答,但它对我不起作用,如果我想添加一个带有多个图像的新对象“Pic”,它会将每个图像添加为一个新对象,例如,如果我添加一个新的“Pic”名称“test1”并为“test1”上传三个图像它将存储3个具有相同名称“test1”的不同图像,但我希望能够同时为相同的'Pic_id'添加3或4个图像
  • 提供有关您的问题的更多详细信息,以便可以复制您的问题
【解决方案2】:

对于这种方法,您需要考虑以下几点,即

确保底层数据库,例如在 SQL Server 的情况下,数据类型必须为VARBINARY(最大值).这会将字节数组数据存储在一行中。

看到你的代码我可以告诉你您实际上需要多行 List<byte[]> 数据类型来存储多个图像字节在单行表内。

由于您只是使用数据类型 byte[] 这意味着在您的foreach 循环您转换为字节数组的最后一张图像将存储在您的变量中,这意味着在您的转化率您正在存储单个图像的字节而不是多个图像的变量。

知道任何数据库基础设施都不允许在单行中存储任何内容的列表,甚至是字节数组,您最终需要使用一对可能的数据库关系将多个文件字节数组的列表分别存储在多行中.

您可能已经发现了一些技巧,但随着图像数量的增加或图像大小的增加,它最终会达到数据类型的最大限制。

简而言之,您需要一对多的关系映射模型来存储多个图像,即使在数据库中也是以字节为单位,您不能通过设计将多个图像字节数组存储在单行中。我希望我能够在这里澄清一些事情。

【讨论】:

    猜你喜欢
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 2017-11-11
    • 2015-02-19
    • 1970-01-01
    相关资源
    最近更新 更多