2

この優れたブログ投稿のアドバイスに従って、EF リポジトリ クラスをテスト可能にするためにリファクタリングを行っています。

https://blog.iannelson.uk/testing-linq-queries/

すべてが順調で、ブログ投稿のように IQueryable 拡張メソッドを連鎖させることもでき、より良心的で読みやすくなっています。

関連する に関連するハードルに遭遇しましたList<>

ドメイン エンティティはユーザーであり、ユーザーには、List<User>標準的なソーシャル ネットワーキング パラダイムであるタイプの友人のコレクションがあります。

ユーザー名が「a」で始まるすべての友達など、ユーザーの友達のサブセットを検索したい。だから私はこれを行います:

    public static IQueryable<IEnumerable<User>> SelectFriendsUsernameStartsWith(this IQueryable<User> userQueryable, string searchQuery)
     {
        return userQueryable.Select(x => x.Friends.Where(y => y.Username.StartsWith(searchQuery)));
     }

問題は、これが私の連鎖を壊すことです。戻り値の型はもはやIQueryable<User>そのIQueryable<IEnumerable<User>>ため、私が書いた拡張メソッドIQueryable<User>は最後に連鎖することはできません。

私の単体テストでは、次のようなコードがあるため、ここでの型の違いは意味がありません。

            IEnumerable<User> users = new HashSet<User>()
                                    {
                                        new User() {Username = "Aaron"},
                                        new User() {Username = "alex"},
                                        new User() {Username = "Ally"},
                                        new User() {Username = "anthony"},
                                        new User() {Username = "bob"},
                                        new User() {Username = "Bill"}
                                    };

        IQueryable<User> userQueryable = users.AsQueryable();

AsQueryable()つまり、 anを呼び出すと、 not (上記の例のように) anIEnumerable<User>が返されます。IQueryable<User>IQueryable<IEnumerable<User>>

誰でもこれに光を当てることができますか?

2 つのタイプの実際の違いは何ですか?また、上記の例でIQueryable<User>notを返すように強制するにはどうすればよいIQueryable<IEnumerable<User>>ですか?

ありがとう!

4

1 に答える 1

7

userQueryable.Select(...に変更userQueryable.SelectMany(...

現在、クエリは次のようになります。

「ユーザーごとに、何かで始まるすべての友達のリストを取得してください」

つまり、いわばリストのリストがあります。 SelectManyは、「このリスト内の各要素を一連の要素に変換し、それらの要素を連結します。結果は、要素のリストのリストではなく、1 つの大きな長い要素のリストになります。

(この返信で「リスト」と言うとき、実際にはシーケンス、つまり IEnumerable/IQueryable を意味します。)

于 2012-05-03T17:11:24.240 に答える