2011-03-08 5 views
2

C#에서 asp.net 4, ef 4를 사용합니다. System.Web.Security을 사용하여 웹 응용 프로그램의 사용자를 관리합니다.컬렉션에서 항목 제거 (MembershipUserCollection) - 열거 연산이 실행되지 않을 수 있습니다.

나는 MembershipUserCollection에 사용자 컬렉션이 있으며 해당 수집자의 foreach 중에 일부 사용자를 제거해야합니다.

루핑 할 때 수집기에서 항목을 제거 할 수 없다고 가정합니다. 해결 방법을 알고 있습니까?

코드 샘플을 보내주십시오. 감사합니다!

 MembershipUserCollection users = Membership.GetAllUsers(); 
     foreach (MembershipUser x in users) 
     { 
      if (!Roles.IsUserInRole(x.UserName, "CMS-AUTHOR")) 
      { 
       users.Remove(x.UserName); 
      } 
     } 

오류 :

Collection was modified; enumeration operation may not execute. 

답변

3

-. 사용자에게 넣어 LINQ를 사용하여

MembershipUserCollection users = Membership.GetAllUsers(); 
    List<string> usersToRemove = new List<string>(); 
    foreach (MembershipUser x in users) 
    { 
     if (!Roles.IsUserInRole(x.UserName, "CMS-AUTHOR")) 
      usersToRemove.Add(x.UserName); 
    } 
    foreach(string userName in usersToRemove) 
     users.Remove(userName); 

이하를 :

var usersToRemove = Membership.GetAllUsers() 
           .Where(user => !Roles.IsUserInRole(user.UserName, "CMS-AUTHOR")) 
           .ToList(); 
usersToRemove.ForEach(user => users.Remove(user.UserName)); 
+0

하이의 의도는 사용자의 컬렉션 임시 목록에서 사용자를 제거 할 수 있지만하지 않을 것이다 귀하의 첫 번째 코드를 시도하고 동일한 문제가 있다고 생각합니다. 사용자 (X. 사용자 이름)에있는 문제가 있습니다. – GibboK

+1

@GlbboK : 내가 꺼내는 것을 잊어 버렸습니다. - 지금 작동해야합니다. – BrokenGlass

+0

감사합니다. ! – GibboK

1

당신이 (명백하게) 이상 열거하는 컬렉션을 수정할 수 없습니다. LINQ를 사용해보십시오.

users.ToList()에서 removeAll (X => Roles.InUserInRole (x.UserName, "CMS 저자")!)

당신은 그것을 통과하는 동안 열거를 수정할 수 없습니다
+0

이 upvoted 내가 문제가있는 것을 깨달았다 전에 - 이것은 단지 OP – BrokenGlass

0

당신은 문제가 무엇인지에 대한 맞아 : 당신은 수정할 수 없습니다 당신이 열거 완료되면 다음 그들 모두를 제거 목록에서 제거 니가 수집하는 동안에 그것을 열거한다. 그것이 허용되면 모든 종류의 문제가 발생할 수 있습니다.

컬렉션에는 ToList(), ToArray() 또는 CopyTo() 메서드가 있어야 컬렉션의 복사본이 만들어집니다. 사본을 복사하고 반복하십시오. 그런 다음 해당 루프에서 원래 컬렉션을 수정할 수 있습니다.

var usersToRemove = from user in users 
        where !Roles.IsUserInRole(x.UserName, "CMS-AUTHOR") 
        select user; 

foreach(var u in usersToRemove) 
{ 
    users.Remove(u); 
} 
0

아마 뭔가를 할 것입니다. 당신이 생각하는 것이 무엇인지 또는 더 잘 구현 될 수 있는지 말해주십시오. 시간 내 주셔서 감사합니다.

 // Take all Users 
     MembershipUserCollection users = Membership.GetAllUsers(); 
     // Create an empty collector for only User in Author 
     MembershipUserCollection usersAuthors = new MembershipUserCollection(); 
     foreach (MembershipUser x in users) 
     { 
      if (Roles.IsUserInRole(x.UserName, "CMS-AUTHOR")) 
      { 
       usersAuthors.Add(x); 
      } 
     } 
0

나는 내 문제에 대한 해결책을 발견

1

문제는 컬렉션을 어떻게 진행하는지에 내재되어 있습니다. foreach를 사용하여 컬렉션을 IEnumerable로 트래버스합니다. IEnumerable을 통해 이동할 때 현재 요소에 대한 참조와 다음 요소로 이동하는 메서드 만 있으면됩니다. 열거 형의 내용을 변경하면 해당 프로세스가 엉망이됩니다. 항상 불변의 것으로 간주하는 콜렉션을 고려하십시오. 요소의 속성을 변경할 수는 있지만 요소를 추가하거나 제거하여 컬렉션의 구조를 변경할 수는 없습니다. 대신이 같은

시도 뭔가 :

MembershipUserCollection users = Membership.GetAllUsers(); 
MembershipUserCollection deletedUsers = new MembershipUserCollection(); 
    foreach (MembershipUser x in users) 
    { 
     if (!Roles.IsUserInRole(x.UserName, "CMS-AUTHOR")) 
     { 
      deletedUsers.Add(x); 
     } 
    } 

foreach(MembershipUser delete in deletedUsers) 
{ 
    users.Remove(delete); 
} 

의 차이 당신이 열거하는 컬렉션을 변경하지 않는 것입니다.당신은 약간의 Linq에 함께이 간단하게 만들 수 있습니다 :

MembershipUserCollection users = Membership.GetAllUsers(); 
//the difference is that the Select method creates a new enumerable that isolates changes to its source 
foreach (MembershipUser x in users.Cast<MembershipUser>().Select(z=>!Roles.IsUserInRole(z.UserName, "CMS-AUTHOR"))) 
{ 
    users.Remove(z); 
} 
+0

설명 주셔서 감사합니다. 첫 번째 코드는 많은 도움이됩니다. Unfotunatelly System.Web.Security와 함께 Linq를 사용할 수 있습니다. – GibboK

+0

컬렉션에서 foreach를 사용할 수 있다면 Linq를 사용할 수 있습니다. MembershipUserCollection 형식은 현재 비 제네릭 IEnumerable 만 구현하므로 컬렉션을 비 제네릭에서 일반 형식으로 변환하면됩니다. 콜렉션에서 OfType () 또는 Cast ()를 호출하여이 작업을 수행 할 수 있습니다. – KeithS

관련 문제