ASP中的二级数据库上下文.净核心

本文关键字:数据库 二级 上下文 核心 ASP | 更新日期: 2023-09-27 18:13:19

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

这样做的问题是,因为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>();

更新

这个问题是有缺陷的,因为我错误地认为。ToArray还将实体从上下文中分离出来。事实上,它们并不分离,只执行查询。

ASP中的二级数据库上下文.净核心

这是因为您使用同一个DbContext同时执行多个事务。如果将.ToListAsync()添加到这行代码中,如

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

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