0

我创建了一个目录搜索器来从每个用户那里提取多个属性。

objSearchADAM = new DirectorySearcher(objADAM);
objSearchADAM.PropertiesToLoad.Add("givenname");
objSearchADAM.PropertiesToLoad.Add("lastlogontimestamp");
ect...
objSearchResults = objSearchADAM.FindAll();

然后我枚举它们,并将 interger8 时间戳转换为标准日期/时间,并保存到 csv 文件

 List<string> timeProps = new List<string>() { "lastlogontimestamp", "accountexpires", "pwdlastset", "lastlogoff", "lockouttime", "maxstorage", "usnchanged", "usncreated", "usndsalastobjremoved", "usnlastobjrem", "usnsource" };

            foreach (SearchResult objResult in objSearchResults)
            {
                objEntry = objResult.GetDirectoryEntry();


                ResultPropertyCollection myResultProp = objResult.Properties;
                foreach (string myKey in myResultProp.PropertyNames)
                {


                    foreach (Object myCollection in myResultProp[myKey])
                    {

                        Object sample = myCollection;


                        if (timeProps.Contains(myKey))
                        {
                            String times = sample.ToString();
                            long ft = Int64.Parse(times);
                            DateTime date;
                            try
                            {

                                date = DateTime.FromFileTime(ft);
                            }
                            catch (ArgumentOutOfRangeException ex)
                            {
                                date = DateTime.MinValue;
                                Console.WriteLine("Out of range: " + ft);
                                Console.WriteLine(ex.ToString());
                            }
                            sample = date;
                            Console.WriteLine("{0}{1}", myKey.PadRight(25), sample);
                            objWriter.WriteLine("{0}{1}", myKey.PadRight(25), sample);
                        }
                        else
                        {
                            Console.WriteLine("{0}{1}", myKey.PadRight(25), sample);
                            objWriter.WriteLine("{0}{1}", myKey.PadRight(25), sample);
                        }
                    }

现在我需要为每个用户创建一个对象,其中包含每个结果中的字符串,我可以将其放入我构建的 SQL 命令中。其中对 SQL 的 LDAP 查询将被赋予name = FirstName 和 lastlogontimestamp = LastLogon 等等。

StringBuilder sb = new StringBuilder();
sb.Append("INSERT INTO activedirectory.dimUserST (FirstName, LastName) VALUES (@FirstName, @LastName)");
loadStagingCommand.Parameters.AddWithValue("@FirstName", FirstName).DbType =    DbType.AnsiString;
ect...
loadStagingCommand.CommandText = sb.ToString();
loadStagingCommand.ExecuteNonQuery();

我尝试在我的第一个 foreach 中使用 IDictionary(类似于在此处找到的代码http://ideone.com/vChWD),但无法使其正常工作。我阅读了有关 IList 和反射的信息,但我不确定如何合并这些。

更新 我研究并找到了 ExpandoObjects 并尝试根据我在此处创建动态对象中看到的内容编写代码 但是我运行这个新代码我返回“employeenumber System.Collections.Generic.List`1[System.Dynamic.ExpandoObject]”

if(employeeNumber.Contains(myKey))
                        {


                        string[] columnNames = { "EmployeeNumber" };
                        List<string[]> listOfUsers = new List<string[]>();
                        for (int i = 0; i < 10; i++)
                        {
                            listOfUsers.Add(new[] { myKey});
                        }

                        var testData = new List<ExpandoObject>();

                        foreach (string[] columnValue in listOfUsers)
                        {
                            dynamic data = new ExpandoObject();
                            for (int j = 0; j < columnNames.Count(); j++)
                            {
                                ((IDictionary<String, Object>)data).Add(columnNames[j], listOfUsers[j]);
                            }
                            testData.Add(data);
                          Console.WriteLine("{0}{1}", myKey.PadRight(25), testData);
                        objWriter.WriteLine("{0}{1}", myKey.PadRight(25), testData);
                        }

                        }

我显然在这里遗漏了一些东西,并且似乎无法解决问题所在。我什至可能会以错误的方式解决这个问题。基本上我需要做的就是从 Active Directory 中提取用户及其属性并放入 SQL 数据库表中。我已经想出了如何分别做这两个,但我不知道如何把它们放在一起。

4

1 回答 1

0

如果 CSV 仅用于缓存结果,则可以使用 Dictionary 来存储搜索结果的内容。将代码分成函数可能会有所帮助:

private static object GetFirstValue(ResultPropertyCollection properties, 
                                       string propertyName)
{
    var propertyValues = properties[propertyName];
    var result = propertyValues.Count == 0 ? null : propertyValues[0];
    return result;
}

然后你可以使用字典来保存属性值,或者你可以创建一个类型:

var results = new List<Dictionary<string, object>>();

foreach(SearchResult objResult in objSearchResults)
{
    var properties = objResult.Properties;

    var propertyDictionary = new Dictionary<string, object> { 
       {"FirstName", GetFirstValue(properties, "givenname")},
       {"LastName", GetFirstValue(properties, "sn")},
       {"UserName", GetFirstValue(properties, "samaccountname")},
    };

    results.Add(propertyDictionary);
}

现在你有一个财产袋清单。

这也可以是一个简单的 LINQ 语句:

var results = objSearchResults.OfType<SearchResult>()
    .Select(s => s.Properties)
    .Select(p => new {
       FirstName = (string)GetFirstValue(properties, "givenname"),
       LastName = (string)GetFirstValue(properties, "sn"),
       UserName = (string)GetValue(properties, "samaccountname"),
       AccountExpires = GetDateTimeValue(properties, "accountexpires")
    });

像这样使用字典:

foreach(var item in results)
{
    var command = new SqlCommand();
    ...
    command.Parameters.AddWithValue("firstName", item["FirstName"]);
    ...
}
于 2013-06-19T15:05:44.113 回答