2

古いメインフレーム システムのアルファベット順ロジックを複製する必要があるアプリケーションを書き直しています。古いメインフレーム システムでは、品目変更レコード ID は A から Z までアルファベット順に並べられ、AA、AB などで始まります。残念ながら、SQL Server と .NET の両方が A と B の間に AA を配置したいので、いくつかの困難を乗り越えなければなりません。最初に長さの降順で変更 ID を並べ替え、次に降順でアルファベット順に並べ替えようとしています。

データを取得するために使用している方法は次のとおりです。

protected internal IList<TeamViewModel> GetTeams(string recordId, string changeId)
{
    var viewModels = (from x in repository.Teams
               where x.RecordId == recordId && x.ChangeId.Length <= changeId.Length && 
                 (x.ChangeId.CompareTo(changeId) == -1 || x.ChangeId.CompareTo(changeId) == 0)
               orderby x.ChangeId.Length descending, x.ChangeId descending, x.ChangeId descending
               group x by x.TeamId into grp
               select grp.FirstOrDefault())
               .ToList()
               .Select(TeamViewModel.FromEntity)
               .ToList();

            return viewModels;
}

各「レコード」には変更レコードのコレクションがあり、各変更レコードには ChangeId プロパティと、変更を行った TeamId があります。個別の teamId ごとに、(古いメインフレームの並べ替えロジックに従って) "最新の" 変更レコードを取得しようとしています。つまり、レコードを並べ替え、チームごとにグループ化し、各グループから最初のレコードを取得しようとしています。

repository.Teams プロパティは、ObjectContext で宣言された ObjectSet をラップする IQueryable を返します。

私の心を本当に驚かせたのは、このクエリをLinqpadで実行すると(デフォルト設定で)正常に動作し、リポジトリのモックをこのクラスに注入したときにこのメソッドが単体テスト内から正常に実行されることです。 SQL データベースにあるものとまったく同じデータを出力します。

しかし、このメソッドが実行時に実行されると、orderbys を含む行が完全に省略されているかのように動作し、実際、orderbys を含む行をコメントアウトすると、Linqpad (既定の構成) で取得したのと同じ結果が得られます。SQL Profiler は、生成された SQL を人間が解読することはほぼ不可能であることを示していますが、「順序」という単語はどこにも含まれていません。

最後に、プロジェクトのアセンブリ内で EF によって生成された型指定されたデータセットを使用するように Linqpad を構成すると、実行時に表示されるのと同じ結果が得られ、orderby が無視されているかのように表示されます。

実際の結果を表示できればいいのですが、データは所有権があるため、Linqpad と私の単体テストによって提供される正しい結果には、「Y」や「Z」などの ID を持つ変更レコードが含まれていると考えてください。 ) 実行時にプロジェクトに表示される結果は、「A」と「B」のようです。

ここで何が起こっているのか、そして同様に重要なことですが、この機能を期待どおりに機能させるために何を変更する必要があるかを誰でも見ることができますか?

私のプロジェクトはエンティティ フレームワーク 5.0 を使用しており、Linqpad 4.42.01 を使用しています。

本当にありがとう!

4

2 に答える 2

4

Group byは、元の注文を保持することを保証するものではありません。注文する場合は、groupbyの後に注文する必要があります。

実際、group byは順序を変更することが保証されているため、group byの前に順序付けすることは意味がありません(グループが1つしかない場合を除く)。

于 2012-10-02T18:19:20.497 に答える
0

私は大げさな推測をします...

ChangeIdはすべて同じ長さです。データベースでは、それらがVARCHARではなくCHAR(10)列などとしてマップされているため、Aは実際には「A」であり、ABは実際には「AB」です。メインフレームとCOBOL、およびオフセット付きのフラットファイルが私の理論的根拠として思い浮かびます。この場合、長さを取得する前に、まずChangeIdをTrim()する必要があります。

于 2012-10-02T18:34:37.750 に答える