2016-10-25 9 views
2

私はGitLabにリンクされたチェンジログWebアプリケーションを作成しています。 GitLabを押してください。C#LINQ変数が "M ####"で始まるかどうかを確認する方法は#が数字です

プッシュを行うには、カスタムIDをメッセージ領域に追加し、それにメッセージを追加します。このカスタムIDは必須です。 M ####/C#####/Merge/Revert。 #は数値(0〜9)を表します。それは、後にフィルタリングするために使用することができるように

アプリケーションは、すべてのプッシュのIDを認識しなければならないなど

以前私は、唯一のM ####とC#####を選択するには、このコードを使用しました一度「Merge」がIDとして使用されると、それも表示されます。

var query = from c in db.Clgcom 
    where c.Prjid == 7 
    && (c.Modid.StartsWith("C") 
    || c.Modid.StartsWith("M")) 
    select c.Modid; 

結果:

M1234, M2345, C12345, M0000, C75843, Merge 

​​を使用すると、動作しない、と私は10の異なるケースを使用するよりも、この他を解決する方法は考えを持っていないしました。

where c.Modid.StartsWith("M0") 
|| c.Modid.StartsWith("M1") 
|| c.Modid.StartsWith("M2") 
|| c.Modid.StartsWith("M3") 
// etc. 

私の問題を解決する良い方法はありますか?

編集:私はEntity Frameworkを使用しているため、正規表現で問題が発生する可能性があります。

+4

このLinq 2 ObjectsまたはLinq 2のSQLまたはEntity Frameworkなど、それはどちらですか? –

+0

@ LasseV.Karlsen Entity Framework – Roy123

+0

その後、10件の場合にとどまります。悪い設計が悪い解決策を育むか、データベース側でクエリのその部分を削除し、最終結果(フィルタリングされていない)をリストまたはIEnumerable に変換し、通常のLinq 2オブジェクトでこの部分を処理します。どちらも理想的ではありません。 –

答えて

4

SQL Serverを対象とする場合はSqlFunctions.PatIndexを使用できます。 string.ContainsのEFマッピングとは異なり、PatIndexはLIKE構文をサポートしています。

「の最初の文字にマッチした」は、特定の式で[LIKE]パターン ..

の最初の出現の開始位置を1つの手段の値を返します。 LIKEと同様に

var query = from c in db.Clgcom 
    where c.Prjid == 7 
     && SqlFunctions.PatIndex("M[0-9][0-9][0-9][0-9]", c.Modid) == 1 
    select c.Modid; 

、SQL ServerはPATINDEXでインデックスを活用することである - この場合には、直接ので、固定アンカー「M」開始の前に、他のチェックに(該当する場合)求めます。実際のプラン選択は異なる場合があります。

もう1つの選択肢は、クライアント側にプルし、正規表現やその他のものでLinq 2オブジェクトを使用することです。これは、ほとんどの作業が適切なインデックスを適用できるSQLで行われるように、元のクエリが制限されるため、「エッジケース」の割合が低い場合でもパフォーマンスの低下はほとんどありません。

var query = (from c in db.Clgcom 
    where c.Prjid == 7 
     && c.Modid.StartsWith("M") // .. LIKE "M%" 
    select c.Modid) 
    .ToList(); // -> IList<string>, in L2O land 

// I'm a fan of this syntax :} 
var re = new Regex(@"^M\d{4}", RegexOptions.IgnoreCase); 
var finalClientFilter = query 
    .Where(s => re.IsMatch(s)); 

一般hullaballoためLike Operator in Entity Framework?を参照してください。

1

あなたがModid値のドメインが設定したアウトとおりに元の質問であることを特定しているなら、あなたは、単に不要な既知の値を除去することによって、残りはM...C...と一致することを意味し、を確認することができますあなたは、インデックスを使用している場合、およびクエリが(StartsWithがデータベースにかなり安いです)

IQueryable<String> query = db.Clgcom 
    .Where(c => 
     c.Prjid == 7 
     && 
     c.Modid != "Merge" 
     && 
     ( 
      c.Modid.StartsWith("M") || c.Modid.StartsWith("C") 
     ) 
    ) 
    .Select(c => c.Modid); 

迅速かつ効率的になります。しかし、あなたがその保証を行うことができない場合は、あなたが露出され、PATINDEXを使用する必要がありますEFにはSqlFunctions.PatIndexと表示されます。

+1

'MaskK'はどうですか?一致するだろう。 – HimBromBeere

+0

@HimBromBeere OPはそれが価値の領域にあるとは言いませんでした。 – Dai

関連する問題