昨天我們建立一個File資料表要來儲存檔案實體路徑
CREATE TABLE [dbo].[File]
(
[Id] CHAR(36) NOT NULL PRIMARY KEY,
[Name] NVARCHAR(50) NOT NULL
)
接下來我們要對Product資料表進行修改,加個欄位儲存圖片FileID,並對File資料表做關聯
ALTER TABLE [dbo].[Product] ADD [FileId] CHAR (36);
ALTER TABLE [dbo].[Product] ADD FOREIGN KEY ([FileId]) REFERENCES [dbo].[File](Id);
修改完後,再一次執行我們的EF Core反向工具,重新建立資料庫模型。
Scaffold-DbContext "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=AspCoreIThelp2020;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" -OutputDir Models Microsoft.EntityFrameworkCore.SqlServer -Force
現在我們新增檔案的Action就要做多個步驟,儲存檔案、對File資料表做寫入、對Product資料表做寫入
[HttpPost]
public async Task<IActionResult> AddProduct(AddProductViewModel productViewModel)
{
if (ModelState.IsValid)
{
//取得使用者上傳檔案的原始檔名
var fileOriginName = Path.GetFileName(productViewModel.File.FileName);
//取原始檔名中的副檔名
var fileExt = Path.GetExtension(fileOriginName);
//為避免使用者上傳的檔案名稱發生重複,重新給一個亂數名稱
var fileNewName = Path.GetRandomFileName();
//指定要寫入的路徑、檔名和副檔名
var filePath = "/data/" + fileNewName + fileExt;
//將使用者上傳的檔案寫入到指定路徑
await using (var stream = System.IO.File.Create(filePath))
{
//執行寫入
await productViewModel.File.CopyToAsync(stream);
}
var file = new Models.File()
{
Id = Guid.NewGuid().ToString(),
Name = fileNewName + fileExt
};
var last = _context.Product.OrderByDescending(d => d.Id).FirstOrDefault();
var product = new Product()
{
Id = last.Id + 1,
Name = productViewModel.Name,
FileId = file.Id
};
_context.File.Add(file);
_context.Product.Add(product);
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(productViewModel);
}