MARS - 阻止数据阅读器关闭的列表列表?

Posted

技术标签:

【中文标题】MARS - 阻止数据阅读器关闭的列表列表?【英文标题】:MARS - List of a list stopping data reader from closing? 【发布时间】:2021-08-10 07:21:15 【问题描述】:

我正在玩一个 ASP Core Identity 项目。

对于管理部分,要将用户添加到角色,我需要该角色的当前成员列表和非成员列表。然后我可以使用复选框或箭头按钮在他们之间移动用户。

我的代码出现错误:

**InvalidOperationException: There is already an open DataReader associated with this Connection which must be closed first.**

当我在数据库连接字符串中启用 MARS 时它可以工作(我正在使用实体):

MultipleActiveResultSets=True

我的代码:

    private RoleManager<IdentityRole> roleManager;
    private UserManager<User> userManager;

    public RoleController(RoleManager<IdentityRole> roleMgr, UserManager<User> userMrg)
    
        // Constructor
        // Role Manager, UserManager Dependancy Injection
        roleManager = roleMgr;
        userManager = userMrg;
    

    public async Task<IActionResult> Update(string id)
    
        IdentityRole role = await roleManager.FindByIdAsync(id);
        List<User> members = new List<User>();
        List<User> nonMembers = new List<User>();
        foreach (User user in userManager.Users)
        
            // We need MARS enabled in connection string
            // MultipleActiveResultSets=True
            // We are creating a list of a list and not closing the data reader?
            var list = await userManager.IsInRoleAsync(user, role.Name) ? members : nonMembers;
            list.Add(user);
        
        return View(new RoleEdit
        
            Role = role,
            Members = members,
            NonMembers = nonMembers
        );
    

所以你会发送一个 id 到 Update() 模块

mysite.com/controller/update/1

然后查看如下列表:

我怎样才能重做这个,这样我就不必使用 MARS 了?我被告知这是一种解决方法,而不是使用它的解决方案。

感谢任何帮助。

【问题讨论】:

你能解释一下你的控制器在做什么吗?看起来您的代码正在从网页获取响应,然后将结果存储在数据库中。我不确定你为什么在 RoleController 中有“userManager = userMrg”行。实体对象通常在项目启动时初始化。在这里,当您从服务器获得可能多次发生的响应时,您正在创建实体数据库。 尝试将foreach语句改成如下:foreach (var user in userManager.Users.ToList()) var list = new List&lt;User&gt;(); if (await userManager.IsInRoleAsync(user, role.Name)) list = members; else list = nonMembers; list.Add(user); var userList = await userManager.Users.ToListAsync(); foreach (var user in userList) var list = new List&lt;User&gt;(); if (await userManager.IsInRoleAsync(user, role.Name)) list = members; else list = nonMembers; list.Add(user); 请显示实际访问数据库的代码。我强烈怀疑它没有处理连接,请参阅C# Data Connections Best Practice? 谢谢吕志,我试试看 【参考方案1】:

感谢吕志,您在 foreach 参数中添加 .ToList() 的想法有效。我的大部分其他代码都保持不变。

public async Task<IActionResult> Update(string id)
    
        IdentityRole role = await roleManager.FindByIdAsync(id);
        List<User> members = new List<User>();
        List<User> nonMembers = new List<User>();
        // Add .ToList() here
        foreach (User user in userManager.Users.ToList())
           
            var list = await userManager.IsInRoleAsync(user, role.Name) ? members : nonMembers;
            list.Add(user);
        
        return View(new RoleEdit
        
            Role = role,
            Members = members,
            NonMembers = nonMembers
        );
    

【讨论】:

以上是关于MARS - 阻止数据阅读器关闭的列表列表?的主要内容,如果未能解决你的问题,请参考以下文章

这里有啥区别阻止它工作?

当阅读器关闭时,C# 尝试调用 Read 无效

Android 如何在阅读列表项计数时停止包含页脚行的 TalkBack

如何获取 LinkedIn 亚马逊阅读列表数据

将每次迭代生成的数据框保存在列表中

数据仓库教程 [关闭]