ASP.NET CORE EF中的辅助Db上下文

时间:2016-10-17 12:03:29

标签: c# asp.net entity-framework .net-core

我有一个发送通知的服务,它需要一个数据库连接来查找订阅。我还有一个控制器(可能更多)做一些逻辑,并发送通知。

问题是,因为DI它使用DbContext的相同实例,所以我在同一个上下文中重新使用DataReader时会抛出错误(可以理解) )。

如果不在DbConnectionString中启用MARS标志,我真的很乐意这样做。鉴于控制器无法使用.ToList()或无法跟踪而“内部”NotificationService需要查找数据库 - 这是否可能?

public class NotificationSystem
{
     private readonly DbContext context;
     public NotificationSystem(DbContext context) { this.context = context;}

     public void SendNotification(string username){
       var subscriptions = context.subscriptions.where(u => u.username == username); 
       // Do some notification stuff
     } 
}

一个简单的控制器

public class SendRemindersController : Controller
{
    private readonly DbContext _context;
    private readonly NotificationSystem _notificationSystem;

    public SendRemindersController(DbContext context, NotificationSystem notificationSystem)
    {
        this._context = context;
        this._notificationSystem = notificationSystem;
    }

    [HttpGet]
    public async Task<IActionResult> Get()
    {
        var reminders = _context.Reminders.Where(r => r.Sent == false && r.RemindAt < DateTime.UtcNow);

        foreach (var reminder in reminders)
        {
            await _notificationSystem.SendNotificationToUser(reminder.UserId);
            reminder.Sent = true;
        }

        await _context.SaveChangesAsync();
        return Ok();
    }
}

startup.cs(是的,我知道我没有使用过接口,以后会重构)。

services.AddDbContext<DbContext>(options => options.UseSqlServer(connection));
services.AddTransient<NotificationSystem, NotificationSystem>();

更新

这个问题存在缺陷,因为我的错误印象是.ToList / .ToArray还将实体与上下文分离。实际上这些不会分离并且只执行查询。

1 个答案:

答案 0 :(得分:1)

因为你使用相同的DbContext来执行多个同步事务。如果您将.ToListAsync()添加到此行代码

var reminders = await _context.Reminders
  .Where(r => r.Sent == false && r.RemindAt < DateTime.UtcNow)
  .ToListAsync();

它将立即检索所有提醒,然后循环内的代码(在此语句之后)可以使用DbContext而不DbContext抛出异常,因为活动结果集仍在迭代