2016-11-02 11 views
0

エンティティフレームワークとLinq Querableを使用しています。複数のwhere句を使用してデータを選択したいとします。複数の場合Lambda式を使用するEFの条件

私のDBには、複数のIDがある可能性があるフィールドがあります。FieldOfInterestID、 ";"で区切られています。 (私が知っている、私は知っているが、それは何かをする後半にあります)、または単に1つのID、それはコンマは私がして、文字列を分割したい

存在しないことを意味します「;」区切り記号、およびそれらのすべてのIDよりも私のwhere節でそれらを使用する。

await ctx.Customer.AsNoTracking() 
    .Where(e => e.UserId == userId) 
    .Select(e => new UserDTO { 
     FieldsOfStudy = ctx.Terms.Where(t => { 
      if (!e.FieldOfInterestID.Contains(";") && t.TermId.ToString() == e.FieldOfInterestID) 
       return true; 
      else if (e.FieldOfInterestID.Contains(";") 

      { 
       string fieldOfInterestIds = e.FieldOfInterestID.Split(";"); 
       foreach (string fieldOfInterestID in fieldOfInterestIds) 
       { 
        if (t.TermId.ToString() == e.FieldOfInterestID) 
         return true; 
        else 
         return false; 
       } 
      } 
      else 
       return false; 
     } 
    }) 
    .ToListAsync().ConfigureAwait(false); 

私の現在の "誤差" 私のwhere句より良いにnot all code paths return a value...

がどのように私は[]の文字列を使用することができます:

私のコードは次のようになりますか?

+0

あなたの 'のforeach()' 0または1回実行されます。それはあなたが意図したものですか?0回の場合がこのエラーの原因ですが、2つ以上の要素で実際に何をしたいのですか? –

+0

@HenkHolterman、いいえ、私はそれを意図していません:) –

+1

あなたは[ゴム製の鴨](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)が必要です –

答えて

2

で:コンパイラの観点から

foreach (string fieldOfInterestID in fieldOfInterestIds) 
{ 
    if (t.TermId.ToString() == e.FieldOfInterestID) 
     return true; 
    else 
     return false; 
} 

foreachのボディ入力することはできませんので、not all code paths return a value...

あなたは体外return false;を移動することによって、それを修正することができます:

foreach (string fieldOfInterestID in fieldOfInterestIds) 
{ 
    if (t.TermId.ToString() == e.FieldOfInterestID) 
     return true; 
} 
return false; 

これはコンパイルエラーを修正しますが、問題を解決することはできません。 LINQ to Entitiesは本体を持つラムダ式(=> { ... })と、string.Splitメソッドをサポートしていないことがわかります。

真の解決策は、異なる基準を必要とする - の代わりに、サポートされていない

e.FieldOfInterestID.Split(";").Contains(t.TermId.ToString()) 

反対が、サポートを正しく処理するために必要とされる;で両方の文字列を囲む

(";" + e.FieldOfInterestID + ";").Contains(";" + t.TermId + ";") 

(文字列の連結とstring.Containsを使用しています)最初、中間および最後のトークン。

最終クエリは、このようなことができます:

var query = ctx.Customer.AsNoTracking() 
    .Where(e => e.UserId == userId) 
    .Select(e => new UserDTO 
    { 
     FieldsOfStudy = ctx.Terms 
      .Where(t => (";" + e.FieldOfInterestID + ";").Contains(";" + t.TermId + ";")) 
    }); 
1

この行は、私には間違っているようだ:

string fieldOfInterestIds = e.FieldOfInterestID.Split(";");

私はそれを変更します

string[] fieldOfInterestIds = e.FieldOfInterestID.Split(";");

また、私は、コードを少し単純化:

ctx.Terms.Where(t => return e.FieldOfInterestID.Split(";").Contains(t.TermId.ToString()));

文字列は、それが返す;文字が含まれていない場合は、文字列[]現在のエラーは、このブランチである一つの項目

+1

有効なremakrks 「すべてのコードパスが値を返すわけではありません」とは何も関係ありません。 –

+0

.containsを使用している場合、私は分割が必要ないと思います。 –

+0

@SGN 'スプリットはもう必要ありませんね' TermIdの値によって決まります。 '" 135 ".Contains(" 3 ")'は 'true'を返します。'" 135; 12 ".Split("; ")。包含(" 3 ")は' false'を返します。 ( "12")は 'true'を返します – bradbury9

関連する問題