2011-02-04 12 views
0

グリッドに表示しているテーブルがあります。同じ列の別の値がある条件を満たす場合、特定の列の値をマスクするように求められています。LINQを使用してオブジェクトリスト内のメンバ変数の値をマスクする方法はありますか?

例を見てみましょう:それには「特別な」

var filteredList = from container in myContainerList 
        let vol = container.Name.ToUpper().Contains("SPECIAL") ? 
                 -1 : container.Volume 
        select new Container() 
        { 
         Name = Name, 
         Volume = vol 
        }; 

これに成功したマスク名前を持つ容器の容積:

public class Container 
{ 
    public string Name { get; set; } 
    public int Volume { get; set; } 
} 

IQueryable<Container> myContainerList; 
// Imagine some code to populate the object 

現在、私はそうのようなボリュームフィールドをマスキングしていますしかし、これは私にとっては非効率的です。

これについては、より良い方法がありますか?

+0

データバインディングの前にアプリケーションサーバー上でコレクションを取得した後で、マスキング部分を移動することができます –

答えて

4

私はコンテナクラスに別のプロパティを追加したい:

public string MaskedVol 
{ 
    get 
    { 
    return (Name.IndexOf("SPECIAL", StringComparison.OrdinalIgnoreCase) != -1) ? "--" : Volume.ToString(); 
    } 
} 
+0

恐らく 'Component'インスタンスの不要な作成を防ぐ良い解決策です。 –

+0

もっと分かりやすくするために、比較を '> = 0'に変更し、'?ボリューム:-1'。また、元のコードでは、 'Volume'は文字列ではなく、数字です。 –

+0

あなたは正しいです - 私は音量ではなく名前を返していました。正しいものが返されることを示すためにコードを更新しました。 – Sean

1

私はショーンに同意読み取り専用プロパティを追加することは、おそらく最良の選択肢であること。あなたがContainerクラスを変更したくない場合は、あなたのLINQクエリは少し簡略化することができるより:

var filteredList = myContainerList.Select(c => new Container { 
    Name = c.Name, 
    Volume = c.Name.ToUpper().Contains("SPECIAL") ? -1 : c.Volume 
}); 
1

をなぜこれがあなたに非効率的なように見えるのでしょうか?
各項目について、ちょうど1回のチェックが行われるため、プロセスのスピードアップの仕方がわかりません。

ToUpperで新しい文字列を作成し、Containsを呼び出す代わりに、IndexOfを使用すると、少し速く、リソースを消費することができます。

次にComponentのマスクVolumeの義務であるかどうかを決定します。
は、それは、クエリ内の混乱を取り除くためにそれに特別なプロパティを宣言している場合:マスキングについて知るための責任ではないContainerさんなら

public class Container 
{ 
    public string Name { get; set; } 
    public int Volume { get; set; } 

    public int MaskedVolume { 
     get { 
      return (Name.IndexOf ("SPECIAL", StringComparison.OrdinalIgnoreCase) >= 0) 
       ? Volume 
       : -1; 
     } 
    } 
} 

、私はラムダがletより良いフィット感であることをElianに同意します:私に警告何

var filteredList = list.Select (c => 
    new Container { 
     Name = c.Name, 
     Volume = (c.Name.IndexOf ("SPECIAL", StringComparison.OrdinalIgnoreCase) >= 0) 
        ? c.Volume 
        : -1 
    }); 

は、しかし、あなただけのリストビューに表示しComponentの別のインスタンスを作成するという事実です。これは本当ですか? Componentがビジネスロジックの一部であり、確かにビジネスロジックの観点から、新しいリストビューが作成されるたびに新しいComponentが作成されないようです。

この場合、ソリューションを再検討する必要があります。 Componentがアプリケーションでどのように使用されているかについて、詳細を教えてください。

+1

私はあなたの例で唯一の注意(拡張など)これがlinq-to-sqlの場合、SQLに正しく変換されず、例外がスローされないことがあります(ちょうど推測、テストしていない)。そしてそれとは別に、lambdasは、Elian Ebbingが投稿した "let's" IMOよりも、これをより読みやすくします。 – Sean

+0

あなたはそうだ、私はそれについて考えなかった。当然、LINQ to SQLの場合、私たちの拡張メソッドは不安ですが、これを指摘してくれてありがとう! –

関連する問題