使用ASP.NET MVC中的实体框架将多个图片上载到SQL Server数据库



我一直在尝试使用实体框架将多张图片上传到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; }
}

DtoModel:

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文件夹中的情况下实现这种方法?

重写控制器代码块如下:

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 server(的数据类型必须为VARBINARY(MAX(。这将把字节数组数据存储在一行中。

看到你的代码,我可以看出你实际上需要多行列表<byte[]>数据类型,将多个图像字节存储在一行表中。

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

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

你可能已经找到了一些破解方法,但随着图像数量的增加或图像大小的增加,它最终会达到数据类型的最大限制。

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

听起来您需要为图像名称创建一个单独的表"test1";以及将用于定位上传到单独表的图像集合的唯一ID(主键(。

上载将需要两次写入,一次写入存储";ImageName";以及唯一密钥和第二写入以单独上传图像,其中列将它们链接回";ImageName";。

最新更新