【发布时间】:2016-06-08 08:59:07
【问题描述】:
情况
我们有一个控制器,用户可以在其中提交任意数量的电子邮件地址来邀请其他(潜在)成员成为朋友。如果在数据库中找不到地址,我们会向该用户发送一封电子邮件。由于用户不必等待此过程完成即可继续工作,因此这是异步完成的。
如果服务器响应缓慢、停机或过载,发送电子邮件可能需要很长时间。 E-Mail 发送者应该根据从 E-Mail 服务器接收到的状态更新数据库,例如当永久失败发生时,例如如果地址不存在,则将好友请求设置为“错误”状态。为此,E-Mail 组件实现了函数SendImmediateAsync(From,To,Subject,Content,Callback,UserArg)。消息已传递(或失败)后,将使用有关传递状态的某些参数调用回调。
当它最终调用委托时,DbContext 对象已经被释放(因为控制器也被释放了),我无法使用 new ApplicationDbContext() 手动创建一个新对象,因为没有接受连接字符串的构造函数。
问题
如何在控制器被释放后很久才写入数据库?我还没有弄清楚如何为自己手动创建一个DbContext 对象。 ApplicationDbContext 类型的对象被传递给 Controller 的构造函数,我希望我可以为自己实例化一个,但是构造函数没有我可以提供的参数(例如连接字符串)。我想避免手动创建 SQL 连接并手动组装 INSERT 语句,并且更愿意使用我们已经设置的实体模型。
代码
代码只显示受影响的段,没有任何可读性错误检查。
[Authorize]
public class MembersController : Controller
{
private ApplicationDbContext _context;
public MembersController(ApplicationDbContext context)
{
_context = context;
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Friends()
{
MailHandler.SendImmediateAsync(FROM,TO,SUBJECT,CONTENT,
delegate (Guid G, object any)
{
//THIS IS NOT WORKING BECAUSE _context IS DISPOSED
var ctx = _context;
Guid Result = (Guid)any; //user supplied argument
if (G != Guid.Empty)
{
ctx.MailConfirmation.Add(new MailConfirmation()
{
EntryId = Result,
For = EntryFor.FriendRequest,
Id = G
});
if (G == MailHandler.ErrorGuid)
{
var frq = _context.FriendRequest.SingleOrDefault(m => m.Id == Result);
frq.Status = FriendStatus.Error;
ctx.Update(frq);
}
ctx.SaveChanges();
}
}, req.Id);
//rendering view
}
}
【问题讨论】:
标签: asp.net-core-mvc entity-framework-core