EF6 Collection被修改;枚举操作可能无法执行

时间:2017-05-29 11:05:06

标签: entity-framework entity-framework-6

我需要将adin用户添加到他们不存在的表(和子表)中。

我有以下代码抛出错误:"收集被修改;枚举操作可能无法执行。"在线" _userPrefsContext.UserRecs.Add(userRec);"

var allUserRecs = _userPrefsContext.UserRecs.ToList();

        foreach (string adminUser in adminUsers.Where(x => x.Length > 0))
        {
            domain = adminUser.Split('\\')[0];
            login = adminUser.Split('\\')[1];

            var userRec = new Domain.UserPrefs.BamUser()
            {
                AdLogonDomain = domain,
                AdLogonId = login,
                UserViews = colUserView
            };

            if (allUserRecs.Where(x => x.AdLogonDomain == domain
                                    && x.AdLogonId == login).Count() == 0)
            {
                //don't currently have a user rec for this login so create one
                _userPrefsContext.UserRecs.Add(userRec);
            }
        }
        _userPrefsContext.SaveChanges();

我在SO上看过类似的帖子,但在每种情况下,他们似乎都在迭代他们添加的集合。就我而言,我只是试图迭代一串字符串。

我哪里出错了?

现在编辑为以下内容(仍然是同样的错误):

            List<string> adminUsers = WebConfigurationManager.AppSettings["AdminUsers"].Split(';').ToList();
        adminUsers = adminUsers.Where(x => x.Length > 0).ToList();

        string domain = "", login = "";
        string userViewString = Helpers.ViewNames.UserView.ToString();

        int viewId = _userPrefsContext.ViewRecs.Where(x => x.Name == userViewString).Select(x => x.BamViewId).Single();

        Domain.UserPrefs.UserView userView = new Domain.UserPrefs.UserView()
        {
            BamViewId = viewId
        };

        List<Domain.UserPrefs.UserView> colUserView = new List<Domain.UserPrefs.UserView>();
        colUserView.Add(userView);

        var allUserRecs = _userPrefsContext.UserRecs.ToList();
        string[] users = new string[adminUsers.Count()];
        int y = 0;
        foreach(string user in adminUsers)
        {
            users[y] = user;
            y++;
        }

        int total = adminUsers.Count;
        for (var i = 0; i < total; i++)
        {

            domain = users[i].Split('\\')[0];
            login = users[i].Split('\\')[1];

            if (allUserRecs.Where(x => x.AdLogonDomain == domain
                                    && x.AdLogonId == login).Count() == 0)
            {
                //don't currently have a user rec for this login so create one
                _userPrefsContext.UserRecs.Add(new Domain.UserPrefs.BamUser()
                {
                    AdLogonDomain = domain,
                    AdLogonId = login,
                    UserViews = colUserView
                });
            }
        }
        _userPrefsContext.SaveChanges();

3 个答案:

答案 0 :(得分:1)

UserViews被定义为域实体,如下所示:

public virtual ICollection<UserView> UserViews { get; set; }

为了完成这项工作,我改变了

var userRec = new Domain.UserPrefs.BamUser()
            {
                AdLogonDomain = domain,
                AdLogonId = login,
                UserViews = colUserView
            };

var userRec = new Domain.UserPrefs.BamUser() { AdLogonDomain = domain, AdLogonId = login, UserViews = colUserView.ToList() };

老实说,我不知道为什么需要.ToList() - 如果有人这么做的话我认为解释可能对很多人有帮助!

答案 1 :(得分:1)

仅供参考 您使用任何替换计数会更好。 任何的工作速度比计数快得多。 使用此代码

 if (!allUserRecs.any(x => x.AdLogonDomain == domain                                   && x.AdLogonId == login))
            {
                //don't currently have a user rec for this login so create one
                _userPrefsContext.UserRecs.Add(new Domain.UserPrefs.BamUser()
                {
                    AdLogonDomain = domain,
                    AdLogonId = login,
                    UserViews = colUserView
                });
            }

替换if

if (allUserRecs.Where(x => x.AdLogonDomain == domain
                                    && x.AdLogonId == login).Count() == 0)
            {
                //don't currently have a user rec for this login so create one
                _userPrefsContext.UserRecs.Add(new Domain.UserPrefs.BamUser()
                {
                    AdLogonDomain = domain,
                    AdLogonId = login,
                    UserViews = colUserView
                });
            }

答案 2 :(得分:0)

问题是你有一个列表,然后你在foreach中运行where子句。这意味着它必须在每次运行时重新查询列表,但如果您在运行期间修改了列表,则查询现在可能是错误的。

这将是一个更好的解决方案:

var allUserRecs = _userPrefsContext.UserRecs.Where(x => x.Length > 0).ToList();

    foreach (string adminUser in adminUsers)
    {
        domain = adminUser.Split('\\')[0];
        login = adminUser.Split('\\')[1];

        var userRec = new Domain.UserPrefs.BamUser()
        {
            AdLogonDomain = domain,
            AdLogonId = login,
            UserViews = colUserView
        };

        if (allUserRecs.Where(x => x.AdLogonDomain == domain
                                && x.AdLogonId == login).Count() == 0)
        {
            //don't currently have a user rec for this login so create one
            _userPrefsContext.UserRecs.Add(userRec);
        }
    }
    _userPrefsContext.SaveChanges();