2012-02-29 6 views
1

が私に簡単に行く直接レポートを取得するには、これが私の最初の質問ですために。私はイントラネットベースのレポートツール(VB.Net + ASP.Net統合Windows認証)を使用して、SQL Server 2005テーブルからユーザーとマネージャを検索し、マネージャレベルのレポートをロールアップします。は、経営者や

この表は現在手動で管理されており、より多くのユーザーのためにアップスケールされる予定であるため、この表はより動的にするように求められています。したがって、Active Directoryにリンクして、手動で入力された現在のものを置き換えるバックエンドのOrgテーブルを作成することを検討しています。

私はADからユーザデータを取得し、快適なんだけど、これを設定するための最良のアプローチのようにわからない、私は次の表を考えていた:

CREATE TABLE dbo.Employees 
(
    EmpID  nvarchar(8) PRIMARY KEY, 
    EmpName  nvarchar(30), 
    EmpNo  nvarchar(15), 
    EmpEmail nvarChar(255), 
    EmpTitle nvarchar(255), 
    MgrID  nvarchar(8) FOREIGN KEY REFERENCES Employees(EmpID) 
) 
GO 

EmpIDNetworkID(になりますsAMAccountName)。

これはADからの入力が必要になります。再帰呼び出しによってフィールドに入力すると思います。

コードをどのように構造化するかわからないので、特定のレベルで開始するすべてのマネージャーの下にあるすべての従業員をキャプチャします。私は現在、特定のマネージャの直属の部下をキャプチャするために、以下の使用してい

Public Function GetDirectReports(ByVal ADFullName As String) As ArrayList 

      Dim adItems As ArrayList = New ArrayList 

      Dim rootEntry As New DirectoryEntry("LDAP://" & ADFullName) 

      Dim searcher As New DirectorySearcher(rootEntry) 
      searcher.PropertiesToLoad.Add("directReports") 
      searcher.PropertiesToLoad.Add("sAMAccountName") 
      searcher.PropertiesToLoad.Add("cn") 

      searcher.PageSize = 5 
      searcher.ServerTimeLimit = New TimeSpan(0, 0, 30) 
      searcher.ClientTimeout = New TimeSpan(0, 10, 0) 

      Dim queryResults As SearchResultCollection 
      queryResults = searcher.FindAll() 

      Dim x As Integer 

      For Each result As SearchResult In queryResults 
       For x = 0 To result.Properties("directReports").Count - 1 
        adItems.Add(New ADReports(result.Properties("directReports")(x), _ 
           ExtractUser(result.Properties("directReports")(x)))) 
       Next 
      Next 
      Return adItems 
     End Function 

     Private Function ExtractUser(ByVal username) As String 
      Return Split(Split(username, "CN=")(1), ",")(0) 
     End Function 

任意のコメントの提案やヘルプは非常に高く評価されるだろう:)

は基本的に私は何をするのかである
+0

VB.NET/.NETフレームワークの**バージョン**を使用していますか?その 'directReports'属性はあなたの会社がADに追加したカスタム属性ですか? –

+0

VS2005 sp1および2.0。いいえ、広告に組み込まれていますAFAIK – SWa

+0

ああ - はい、それは 'Reports'(LDAP表示名:' directReports')と呼ばれています。 –

答えて

1

単に広告全体を再帰し、関連する情報を必要とするすべてのユーザーを引き出し、SQL Serverに格納します。列挙している間、階層について心配しないでください。後でそれらを扱います。

データがSQL Server内に格納されたら、たとえば次のように作成できます。

注:sAMAccountNameは安定していることは保証されていません(稀ではありますが、可能性があります)。これは一般的なCTE(Common Table Expression) - 多分あなたは各ユーザーの一意の識別子として別の項目が必要でしょうか?あなたの会社はuserID属性などを使用していますか?または、samAccountNameの代わりにADユーザーGUID(これは永遠に変わらない)を使用できますか?

また、sAMAccountNameを使用することを選択した場合、長さは最大20文字になりますので、NVARCHAR(8)で十分ではありません。また:本当にユニコード文字列が必要ですか?これらの文字列は、Unicode以外の文字列の2倍の長さになっています。ちょうど尋ねるだけで、必要な場合があります。

人工的なEmployeeIDINT IDENTITY)の列をテーブルに追加して、そのテーブルの良好なクラスタリングキーのすべての要件を処理することができます。 A nvarchar(20)はまず可変長であり、それほど優れているわけではなく、最大でも40バイトになる可能性があります。これもやはり最適ではありません。

+1

OK、それはテーブル構造上のあなたのポインタのために意味があり、ありがとう。私は提案された私の一意の識別子を変更します。あなたの答えをありがとう、あなたはそれを明確にし、非常に有用であった – SWa

1

このコードスニペットを使用して、特定の従業員のマネージャ名を取得することができます。あなたがマネージャーの部下を知りたければ、ダイレクトレポートをマネージャーに置き換えてください。

lblUser.Text = My.User.Name 
    Dim _UserName As String = GetDomainUserName(My.User.Name) 
    Dim context As PrincipalContext = New PrincipalContext(ContextType.Domain) 


    ' find a user 
    Dim user As UserPrincipal = UserPrincipal.FindByIdentity(context, lblUser.Text) 

    Dim allUsers As New ArrayList() 
    Dim searchRoot As New DirectoryEntry("LDAP://DOMAIN") 
    Dim search As New DirectorySearcher(searchRoot) 
    'search.Filter = "(&(objectClass=user)(manager=" + user.DistinguishedName + "))" 
    search.Filter = "(&(objectClass=user)(directReports=" + user.DistinguishedName + "))" 
    search.PropertiesToLoad.Add("samaccountname") 

    Dim result As SearchResult 
    Dim resultCol As SearchResultCollection = search.FindAll() 
    If resultCol IsNot Nothing Then 
     For counter As Integer = 0 To resultCol.Count - 1 
      result = resultCol(counter) 
      If result.Properties.Contains("samaccountname") Then 
       allUsers.Add(DirectCast(result.Properties("samaccountname")(0), [String])) 
      End If 
     Next 
    End If 
関連する問題