2

NFR コードの複雑さの基準を満たすために、さまざまなメソッドに分割する必要がある複雑なクエリがあります。

望ましい基準を満たすためだけにこれが悪いことはわかっていますが、このクエリを小さなチャンクに分割できますか?

var query = (from a1 in a 
             join b1 in b
                 on a1.id1 equals b1.id1
             join c1 in c
                 on b1.id equals c1.id
             join d1 in d
                 on c1.id1 equals d1.id
             where (d1.Contains("text"))
             select d1);
4

2 に答える 2

4

Linq-to-SQL を使用しているか、Linq-to-Entities を使用しているかに応じて、リレーションは既にコードで表現されている可能性があり、ナビゲーション プロパティを簡単に利用できます。

from d1 in d 
where d1.C.B.A != null
     && d1.Contains("text")
select d1;

Entity Framework は、コード内で発生する可能性のある null 参照例外を無視することを認識します。これは、これをクエリとして表現し、実際にはコードを実行しないためです。

これが不可能な場合は、Visual Studio 2012 コードの複雑さの機能を使用していると想定しています。これは、コードの複雑さではなく、ILの複雑さを調べます。Linq クエリは内部で多くの複雑さを生成する傾向がありますが、これはコードには表示されません。

この非常に読みやすいクエリを複数のメソッドに分割すると、読みやすさが問題になる可能性があるという警告を人為的に修正しようとしますが、クラスレベルでコードの複雑さが増すため、複雑さの警告は無視します。

于 2015-03-14T12:26:59.727 に答える
1

このクエリは壊れる可能性があります(正確にはこれであり、はるかに複雑な実際のクエリではありません:-))

IQueryable<atype> query = a;

IQueryable<btype> query2 = from a1 in query
                           join join b1 in b on a1.id1 equals b1.id1
                           select b1;

IQueryable<ctype> query3 = from b1 in query2
                           join join c1 in c on b1.id1 equals c1.id1
                           select c1;

これらはそれぞれ、次のような署名を持つメソッドに入れることができます。

IQueryable<ctype> JoinQuery2(IQueryable<btype> query2)
{
    IQueryable<ctype> query3 = from b1 in query2
                               join join c1 in c on b1.id1 equals c1.id1
                               select c1;
    return query3;
}

このタイプのクエリは、結合するたびに「古い」タイプを破棄するため、簡単に壊れる可能性があります (したがって、 の最後にquery2は のみがありselect b1、 はありませんselect a1+b1)。両方のオブジェクトを保持する必要がある場合は、匿名オブジェクトである必要があり、匿名オブジェクトであるためnew { a1, b1 }渡すことができないため、実行できません。

アナライザーはメソッドの完全なチェーンを認識しないため、単にクエリを複数の変数に分割するだけで NPR の問題が解決することに注意してください。

var query2 = from a1 in a
             join join b1 in b on a1.id1 equals b1.id1
             select b1;

var query3 = from b1 in query2
             join join c1 in c on b1.id1 equals c1.id1
             select c1;

この場合、次のような匿名オブジェクトを使用することもできます

var query1 = from a1 in a
             join join b1 in b on a1.id1 equals b1.id1
             select new { a1, b1 };

var query3 = from a1b1 in query2
             join join c1 in c on a1b1.b1.id1 equals c1.id1
             select new { a1b1.a1, a1b1.b1, c1 };

等々。

于 2015-03-14T12:18:31.300 に答える