LINQ.Except()
子句出现问题。
我得到了一个唯一的、排序的、当前的用户名列表。我可以在我们公司的广告中查找这些,并为每个广告生成UserPrinciple
项目的列表。此列表将成为AD组的当前成员。
假设AD组在过去某个时候已经填充,我想用当前用户的UserPrinciple
列表修改成员资格。我知道我可以adGroup.Members.Clear();
,然后在当前用户列表上循环执行adGroup.Member.Add(user);
。这需要一段时间,我希望有一种更有效的方法来做到这一点。
我找到了LINQ.Except()
子句,看起来它应该起作用。。。如果我能做到的话。
我试过一些简单的例子,比如:
var t1 = new List<int>{1,2,3,4,5,6,7,8,9};
var t2 = new List<int>{1,55,9};
var t3 = new List<int>{9,8,7,6,5,4,3,2,1};
var t1_t2 = t1.Except(t2).ToList();
// yeilds: 2,3,4,5,6,7,8
var t2_t1 = t2.Except(t1).ToList();
// yeilds: 55
var t1_t3 = t1.Except(t3).ToList();
// yeilds: empty list
然而,尝试使用UserPrinciple
的列表执行此操作的方式不同。
假设AD组和用户列表是相同的。如果我试图获得要从AD组中删除的项目列表,我会尝试:
using var ctx = new PrincipalContext(ContextType.Domain, null, "MyADuser", "a-password");
var groupDn =
"CN=My Test Group,OU=Groups,OU=MyUnit,DC=ad,DC=MyCompany,DC=com";
using var group = GroupPrincipal.FindByIdentity(ctx, groupDn);
var userList = GetUserList();
var removeList = group.Members.Except(userList).ToList();
我希望removeList
为空,但它包含所有成员记录。同样,如果我往另一个方向走:
var addList = userList.Except(group.Members).ToList();
我得到了整个成员名单。我本以为会有一张空单子。
我曾想过我可能需要实现IEqualityComparitor
,但我显然不够聪明。
我错过了什么?我应该只是踢和.Clear()
的AD组,并重建它每次?
感谢@Ralf的提示和一篇文章(来自dotnettutorials.net),我有了一个比较器。
编辑
private class MemberComparer : IEqualityComparer<Principal> {
public bool Equals(Principal x, Principal y) {
//First check if both object reference are equal then return true
if (ReferenceEquals(x, y)) {
return true;
}
//If either one of the object reference is null, return false
if (x is null || y is null) {
return false;
}
var xName = x.SamAccountName ?? "" + x.DistinguishedName ?? "";
var yName = y.SamAccountName ?? "" + y.DistinguishedName ?? "";
//Comparing all the properties one by one
return xName == yName;
}
public int GetHashCode(Principal obj) {
//Get the ID hash code value
var idHashCode = obj.Sid == null ? 0 : obj.Sid.GetHashCode();
//Get the Name HashCode Value
var name = obj.SamAccountName ?? "" + obj.DistinguishedName ?? "";
var nameHashCode = name == "" ? 0 : name.GetHashCode();
return idHashCode ^ nameHashCode;
}
}
这些编辑是基于我们当地AD专家关于使用哪些字段的一些建议。