无法使用外键将多个文件保存到数据库
Cannot save multiple files to database with Foreign Key
在我的 MVC 应用程序中,我有两个 table,分别称为 Ticket 和 Attachment,我想为每个文件保存附件票。问题是:创建新工单 时,我需要使用 TicketID 保存多个附件。所以,我想我应该在 Ticket table 中创建一个新的 ticket,然后获取它的 ID 并将所有具有此 TicketID 的附件循环保存到 Attachment table 中。我看过很多网站和 Whosebug,但在那些页面上没有这样的问题或解决方案。任何的想法?
注意:我使用Entity Framework代码优先,但我也可以使用存储过程或SQL命令进行此操作。
以下是这两个模型:
public class Ticket
{
[Key]
public int ID { get; set; }
public string Description { get; set; }
//... removed for clarifty
}
public class Attachment
{
[Key]
public int ID { get; set; }
//Foreign key for Ticket
public int TicketID { get; set; }
public byte[] FileData { get; set; }
public string FileMimeType { get; set; }
}
和控制器方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = null)] TicketViewModel viewModel
/* contains both model: Ticket and Attachment */, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
//??? First I need to save Ticket
repository.SaveTicket(viewModel.Ticket);
foreach(var f in files)
{
viewModel.Attachment.FileMimeType = f.ContentType;
viewModel.Attachment.FileData = new byte[f.ContentLength];
f.InputStream.Read(viewModel.Attachment.FileData , 0, f.ContentLength);
//??? Then save all attachment. But no idea how to get TicketID
repository.SaveAttachment(viewModel.Attachment);
}
}
return View();
}
ID 属性 将在 SaveChanges 后由 EF 自动填充。然后您的代码就可以使用它。我假设 viewModel.Ticket object 是保存到数据库中的实际 object。如果不行,还请postSaveTicket
方法。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = null)] TicketViewModel viewModel
/* contains both model: Ticket and Attachment */, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
// assumes viewModel.Ticket is the actual entity saved, and SaveChanges is called.
repository.SaveTicket(viewModel.Ticket);
foreach(var f in files)
{
viewModel.Attachment.FileMimeType = f.ContentType;
viewModel.Attachment.FileData = new byte[f.ContentLength];
f.InputStream.Read(viewModel.Attachment.FileData , 0, f.ContentLength);
// fill ticket id
viewModel.Attachment.TicketID = viewModel.Ticket.ID;
repository.SaveAttachment(viewModel.Attachment);
}
}
return View();
}
如果您想在一次交易中完成所有事情,您可以立即添加孩子,SaveChanges 将保存所有 objects:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = null)] TicketViewModel viewModel
/* contains both model: Ticket and Attachment */, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
var ticket = viewModel.Ticket;
foreach(var f in files)
{
var attachment = new Attachment();
attachment.FileMimeType = f.ContentType;
attachment.FileData = new byte[f.ContentLength];
f.InputStream.Read(attachment.FileData , 0, f.ContentLength);
ticket.Attachments.Add(attachment);
}
// this will save the ticket and attachments
repository.SaveTicket(ticket);
}
return View();
}
您的票 class 必须如下所示:
public class Ticket
{
[Key]
public int ID { get; set; }
public string Description { get; set; }
// EF will now to use the foreign key to the attachment table
public virtual ICollection<Attachment> Attachments { get; set; }
}
在我的 MVC 应用程序中,我有两个 table,分别称为 Ticket 和 Attachment,我想为每个文件保存附件票。问题是:创建新工单 时,我需要使用 TicketID 保存多个附件。所以,我想我应该在 Ticket table 中创建一个新的 ticket,然后获取它的 ID 并将所有具有此 TicketID 的附件循环保存到 Attachment table 中。我看过很多网站和 Whosebug,但在那些页面上没有这样的问题或解决方案。任何的想法?
注意:我使用Entity Framework代码优先,但我也可以使用存储过程或SQL命令进行此操作。
以下是这两个模型:
public class Ticket
{
[Key]
public int ID { get; set; }
public string Description { get; set; }
//... removed for clarifty
}
public class Attachment
{
[Key]
public int ID { get; set; }
//Foreign key for Ticket
public int TicketID { get; set; }
public byte[] FileData { get; set; }
public string FileMimeType { get; set; }
}
和控制器方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = null)] TicketViewModel viewModel
/* contains both model: Ticket and Attachment */, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
//??? First I need to save Ticket
repository.SaveTicket(viewModel.Ticket);
foreach(var f in files)
{
viewModel.Attachment.FileMimeType = f.ContentType;
viewModel.Attachment.FileData = new byte[f.ContentLength];
f.InputStream.Read(viewModel.Attachment.FileData , 0, f.ContentLength);
//??? Then save all attachment. But no idea how to get TicketID
repository.SaveAttachment(viewModel.Attachment);
}
}
return View();
}
ID 属性 将在 SaveChanges 后由 EF 自动填充。然后您的代码就可以使用它。我假设 viewModel.Ticket object 是保存到数据库中的实际 object。如果不行,还请postSaveTicket
方法。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = null)] TicketViewModel viewModel
/* contains both model: Ticket and Attachment */, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
// assumes viewModel.Ticket is the actual entity saved, and SaveChanges is called.
repository.SaveTicket(viewModel.Ticket);
foreach(var f in files)
{
viewModel.Attachment.FileMimeType = f.ContentType;
viewModel.Attachment.FileData = new byte[f.ContentLength];
f.InputStream.Read(viewModel.Attachment.FileData , 0, f.ContentLength);
// fill ticket id
viewModel.Attachment.TicketID = viewModel.Ticket.ID;
repository.SaveAttachment(viewModel.Attachment);
}
}
return View();
}
如果您想在一次交易中完成所有事情,您可以立即添加孩子,SaveChanges 将保存所有 objects:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = null)] TicketViewModel viewModel
/* contains both model: Ticket and Attachment */, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
var ticket = viewModel.Ticket;
foreach(var f in files)
{
var attachment = new Attachment();
attachment.FileMimeType = f.ContentType;
attachment.FileData = new byte[f.ContentLength];
f.InputStream.Read(attachment.FileData , 0, f.ContentLength);
ticket.Attachments.Add(attachment);
}
// this will save the ticket and attachments
repository.SaveTicket(ticket);
}
return View();
}
您的票 class 必须如下所示:
public class Ticket
{
[Key]
public int ID { get; set; }
public string Description { get; set; }
// EF will now to use the foreign key to the attachment table
public virtual ICollection<Attachment> Attachments { get; set; }
}