1

会社を表すツリーのようなものがあり、次のテーブルとしてデータベースに保存されます。

  ID       ParentID     Name
 ==================================
   1        NULL        Company
   2        1           Division one
   3        1           Division two
   4        1           Division three
   5        2           Department 1.1
   6        3           Department 2.1
   7        3           Department 2.2
   8        3           Department 2.3
   9        4           Department 3.1
  10        NULL        Company 2

ここで、ユーザーに権限を与えるとき、上の表からグループに割り当てる必要があります。グループに割り当てると、子グループに対する権限が自動的に付与されます。1グループくらいなら簡単に確認できます。ただし、たとえば、ユーザーに (部門 2) のアクセス許可を与え、ユーザーが (部門 2.2) でトランザクションを行っている場合、ユーザーは既に親グループで許可されているため、トランザクションを自動的に許可する方法を見つける必要があります。対象のグループをチェックする再帰的な方法しか考えられません。ユーザーがそのグループにアクセス許可を持っておらず、親グループがある場合は、同じ方法を思い出してその親を認証し、ユーザーが許可されているグループが見つかるまで繰り返します。または root グループに到達し、ユーザーを認証しません。子はその中に別の子を持つことができることなどを覚えておいてください。

これをより良い方法で行う方法はありますか?Linq または単純な古い T-SQL のどちらを使用していますか?

4

3 に答える 3

1

AFAIK再帰関数は唯一の方法です。少し前に私は同様の質問をしましたが、EFもLINQもそれを計算できないことに気づきました。

私の質問:LINQを使用してサブカテゴリのすべてのアイテムを取得する

于 2012-10-22T22:33:06.723 に答える
1

親のすべての子をチェックしたいということは理解しています。

with tmp as (
  select id, parentId, name, 0 as iteration
  from t
  where id = 3 -- you wanted parent
  union all
  select parent.id, parent.parentId, parent.name, child.iteration + 1
  from tmp child
  join t parent on child.id = parent.parentId
)
select id, parentId, name from tmp
order by iteration

デモ: http://sqlfiddle.com/#!3/b5d1d/10

于 2012-10-22T23:12:04.473 に答える
0

これはうまくいきます:

public class Permission
{
  public ID { get; set; }
  public ParentID { get; set; }
  public Name { get; set; }
}

int userPermissionID = 3;  // Division two
int objectPermissionID = 7; // Department 2.2
bool hasAccess = false;

List<int> check = new List<int>();
check.add(objectPermissionID);

hasAccess = userPermissionID == objectPermissionID;

while(!hasAccess && check.count > 0)
{
  var permissions = context.Permissions
    .Where(p => check.Contains(p.ID))
    .ToList();

  hasAccess = permissions.Any(p => p.ParentID = userPermissionID)

  check = permissions.Select(p => p.ParentID).ToList();
}

if (hasAccess)
{
  ..

X 回までデータベースにアクセスします。ここで、X は使用可能なサブブランチの数です。

于 2012-10-22T22:50:03.083 に答える