如何将 LINQ ".Except()" 与 AD 用户对象一起使用?



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专家关于使用哪些字段的一些建议。

最新更新