0

アカウントのリストを特定の順序で注文できるようにする必要があります。それらはすべて、1 レベルの親子関係を持っています。

したがって、データは次のようになります。

AccountID    AccountName    ParentID
1            Blue           NULL
2            Red            NULL
3            Green          NULL
4            Yellow         3
5            Orange         2
6            Purple         1
7            Voilet         1
8            Gold           2

etc...

次のようなドロップダウン リストを設定する必要があります (以下)。これは、最初に NULL の ParentID を持つ AccountID によってアルファベット順に並べられ、次にその親の子アカウントもアルファベット順に並べられます。子アカウントの「ダッシュ」は視覚効果のために追加されているだけなので、心配する必要はありません。

Blue
- Purple
- Voilet
Green
- Yellow
Red
- Gold
- Orange

以前に使用していたコード (以下) を次に示しますが、約 30 個のアカウントがあると、このエラーが発生し始めます。

SQL ステートメントの一部のネストが深すぎます。クエリを書き直すか、小さなクエリに分割します。

Public Function GetAllActiveAccountsForAccountSwitcher() As IEnumerable(Of Models.AccountDropDownListModel)
    Dim isFirst As Boolean = True
    Dim list As IQueryable(Of Models.AccountDropDownListModel) = Nothing

    Dim parentAccts As IQueryable(Of Account) = From a As Account In dc.Accounts _
            And a.ParentID Is Nothing _
            Order By a.AccountName

    For Each parentAcct In parentAccts

        Dim parent = From a In dc.Accounts Where a.AccountID = parentAcct.AccountID _
            Select New Models.AccountDropDownListModel _
            With { _
                .AccountID = a.AccountID,
                .AccountName = a.AccountName
            }
        If isFirst Then
            list = parent
            isFirst = False
        Else
            list = list.Union(parent)
        End If

        Dim child = From a As Account In dc.Accounts Where a.ParentID = parentAcct.AccountID _
           Select New Models.AccountDropDownListModel _
                With { _
                    .AccountID = a.AccountID,
                    .AccountName = "- " & a.AccountName
                }
        list = list.Union(child)

    Next

    Return list
End Function

C# または VB.NET の例は問題ありません。私は不可知論者ですが、linq-to-sql を使用する必要があります。ストアド プロシージャは、私の状況ではオプションではありません。

更新: これは、VB にアレルギーのある人のための私の元のコードの c# です...

public IEnumerable<Models.AccountDropDownListModel> GetAllActiveAccountsForAccountSwitcher()
{
    bool isFirst = true;
    IQueryable<Models.AccountDropDownListModel> list;

    IQueryable<Account> parentAccts = from a in dc.Accounts & a.ParentID == null orderby a.AccountName;


    foreach (void parentAcct_loopVariable in parentAccts) {
        parentAcct = parentAcct_loopVariable;
        var parent = from a in dc.Accountswhere a.AccountID == parentAcct.AccountID select new Models.AccountDropDownListModel {
            AccountID = a.AccountID,
            AccountName = a.AccountName
        };
        if (isFirst) {
            list = parent;
            isFirst = false;
        } else {
            list = list.Union(parent);
        }

        var child = from a in dc.Accountswhere a.ParentID == parentAcct.AccountID select new Models.AccountDropDownListModel {
            AccountID = a.AccountID,
            AccountName = "- " + a.AccountName
        };
        list = list.Union(child);

    }

    return list;
}
4

2 に答える 2

1

RRrrrgggg私はとてもばかです。これは非常に単純であることがわかりました。モデルに「SortName」文字列を追加し、その後で並べ替えました。

Public Function GetAllActiveAccountsForAccountSwitcher() As IEnumerable(Of Models.AccountDropDownListModel)
    Dim parentAccts As IQueryable(Of Account) = From a As Account In dc.Accounts

    Return parentAccts.Select(Function(a) New Models.AccountDropDownListModel _
                With { _
                    .SortName = IIf(a.ParentID Is Nothing, a.AccountID, a.ParentID & "_Child"),
                    .AccountID = a.AccountID,
                    .AccountName = IIf(a.ParentID Is Nothing, a.AccountName, "- " & a.AccountName)
                }).OrderBy(Function(a) a.SortName).ThenBy(Function(a) a.AccountName)
End Function
于 2013-09-25T16:39:47.993 に答える
0

書き直した。本来あるべきように、トリガーによって適切な並べ替え順序を維持することはできないため、少し工夫する必要があります。これがLinq2Sqlで直接機能するかどうかはわかりませんが、すべてのレコードが必要なので、それらをすべてにプルしてList<Account>から、クライアント側でそのリストをソートできます。

次の順序で並べ替えます。

  1. 親の名前 OR または私たち自身の名前 if null( 1 つの親からのすべてのアイテムをまとめてグループ化する)
  2. 行が親であるという事実 (親を一番上に置きます)
  3. 名前 (親に影響を与えずに子を注文します)

これは、スキーマに一致するオブジェクトのリストに対して機能するクエリです。

var result = 
    from a in Accounts
    // Get one value that is the same for both a parent & a child.
    // Since we need to sort alphabetically, we use the
    // parent name.  We only have the ID (parentId), so we need to do
    // a lookup into the list to get the parent.Name.  If the parentId
    // is null, it means we ARE the parent, so we use our own name
    let sortingGroup = Accounts.Where(x => x.Id == a.ParentId)
                            .Select(x => x.Name)
                            .FirstOrDefault() ?? a.Name
    orderby
        sortingGroup,
        a.ParentId == null descending,
        a.Name
    select new
        {
            SortingGroup = sortingGroup,
            Id = a.Id,
            Name = a.Name,
            ParentId = a.ParentId
        };
    }
于 2013-09-25T15:39:42.003 に答える