繁体   English   中英

使用ASP.NET MVC中的Entity Framework将多张图片上传到SQL服务器数据库

[英]Upload multiple pictures to SQL Server database using Entity Framework in ASP.NET MVC

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

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

我尝试将图片作为 DtoModel 中的ICollection<IFormFile> Pic并将它们转换为主要 model 中的 byte[] 以将它们存储在数据库中,但它不起作用,我只是将一张图片从许多我存储在数据库中已上传。

初级 model:

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

}

Controller:

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

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

重写您的 controller 代码块,如下所示:

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();

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

确保基础数据库,例如 SQL 服务器的数据类型必须为VARBINARY(MAX) 这会将字节数组数据存储在一行中。

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

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

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

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

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

听起来您需要为图像名称“test1”和唯一 ID(主键)创建一个单独的表,该 ID 将用于定位上传到单独表的图像集合。

上传需要两次写入,一次写入存储“ImageName”和唯一键的表,第二次写入单独上传图像,并使用将它们链接回“ImageName”的列。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM