2016-11-02 41 views
0

我使用實體框架和LINQ Querable,我想用一個多where子句選擇一些數據。多個地方使用lambda在EF條件表達式

在我的數據庫中,我有一個字段可能有多個ID FieldOfInterestID,用「;」分隔。 (我知道,我知道,但它是來不及做的東西),或只是一個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); 

我目前的 「錯誤」 是not all code paths return a value...

我如何使用字符串[]在我的where子句更好?

+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到實體不支持與車身(=> { ... })lambda表達式,也string.Split方法。

真正的解決辦法需要一個不同的標準 - 代替不受支持

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

相反,但支持(使用了字符串連接和string.Contains

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

圍兩個串與;需要正確處理第一,中間和最後一個令牌。

最後的查詢可能是這樣的:

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,我想我不需要再使用Split了,對吧? –

+0

@SGN'我想我不需要Split了'這取決於TermId的值。 '「135」.Contains(「3」)'會返回'true'。類似於'String.IndexOf' '「135; 12」.Split(「;」)。Contains(「3」)'將返回'false' '「135; 12」.Split(「;」)。Contains (「12」)'會返回true – bradbury9