2017-04-19 45 views
1

我對Linq查詢中的字符串使用Split方法,但只需要第二個元素。我得到一個「System.InvalidOperationException:‘:ArrayIndex無法識別的表達式節點’」上下面的代碼:訪問LINQ to Entities集內的數組元素

var RMA_stops_all = (from rma in rDb.DistributionStopInformations 
         join line in rDb.DistributionLineItems on rma.UniqueIdNo equals line.UniqueIdNo 
         where line.RmaNumber != null 
         && 
         (line.DatetimeCreated > Convert.ToDateTime(dateToCheck_rma) && 
         line.DatetimeCreated < Convert.ToDateTime(dateToCheck_rma).AddDays(7)) 
         && rma.CustomerNo == TNGCustNo 
         select new 
         { 
          dtCreated = line.DatetimeCreated, 
          UniqueIdNo = rma.UniqueIdNo, 
          RmaNumber = line.RmaNumber, 
          RmaOriginalUniqueId = line.RmaOriginalUniqueId, 
          ItemSequenceNo = line.ItemSequenceNo, 
          ItemNumber = line.ItemNumber, 
          goodRMA_flag = line.RmaNumber.Contains("/078"), 
          rmaGood = line.RmaNumber.Split(new string[] { "/" }, StringSplitOptions.None)[1] 
         }).ToArray(); 

如果刪除[1]在陣列上它的工作原理和我可以訪問細兩個元件對於整個數據集:

foreach (var item in RMA_stops_all) 
     { 
     var right = RMA_stops_all.First().rmaGood[1]; 
     var left = RMA_stops_all.First().rmaGood[0]; 
      Console.WriteLine("left {0} - right{1} ",left.ToString(), right.ToString()); 
     } 

EDIT - duh。上面的「測試」完全沒有用(如同指出的那樣) - 但是,下面證明它正常工作(一些返回值只有1個元素,因此額外的if塊 - 輸出如預期的那樣:從dbMonitor

foreach (var item in RMA_stops_all) 
      { 
       string right, left; 
       if (item.rmaGood.Length == 1) 
       { 
        left = item.rmaGood[0].ToString(); 
        right = "Not there"; 
       } 
       else 
       { 
       left = item.rmaGood[0].ToString(); 
       right = item.rmaGood[1].ToString(); 
       } 
       Console.WriteLine("left {0} - right{1} ", left, right); 
      } 

SQL輸出:

SELECT t2.datetime_created AS "DatetimeCreated", 
     t1.unique_id_no AS "UniqueIdNo", 
     t2.rma_number AS "RmaNumber", 
     t2.rma_original_unique_id AS "RmaOriginalUniqueId", 
     t2.item_sequence_no AS "ItemSequenceNo", 
     t2.item_number AS "ItemNumber", 
     (t2.rma_number LIKE :p3) OR (t2.rma_number LIKE :p4) AS "C1", 
     t2.rma_number AS "RmaNumber1" 
FROM cops_reporting.distribution_stop_information t1 
INNER JOIN cops_reporting.distribution_line_items t2 
    ON t1.unique_id_no = t2.unique_id_no 
WHERE (t2.rma_number IS NOT NULL) 
    AND (t2.datetime_created > :p0) 
    AND (t2.datetime_created < :p1) 
    AND (t1.customer_no = :p2) 
+0

EF支持'String.Split'? SQL查詢的外觀如何? –

+0

似乎沒有字符串拆分 –

+0

但它運行並返回一個我可以訪問的數組? –

回答

1

我不知道LINQ到實體曾獲得直接一些SQL函數,所以這可能爲你工作:

var RMA_stops_all = (from rma in rDb.DistributionStopInformations 
        join line in rDb.DistributionLineItems on rma.UniqueIdNo equals line.UniqueIdNo 
        where line.RmaNumber != null 
        && 
        (line.DatetimeCreated > Convert.ToDateTime(dateToCheck_rma) && 
        line.DatetimeCreated < Convert.ToDateTime(dateToCheck_rma).AddDays(7)) 
        && rma.CustomerNo == TNGCustNo 
        select new 
        { 
         dtCreated = line.DatetimeCreated, 
         UniqueIdNo = rma.UniqueIdNo, 
         RmaNumber = line.RmaNumber, 
         RmaOriginalUniqueId = line.RmaOriginalUniqueId, 
         ItemSequenceNo = line.ItemSequenceNo, 
         ItemNumber = line.ItemNumber, 
         goodRMA_flag = line.RmaNumber.Contains("/078"), 
         rmaGood = line.RmaNumber.Substring(line.RmaNumber.IndexOf("/")+1) 
        }).ToArray(); 

假設RmaNumber看起來像#/#,並且沒有額外的斜槓你想避免。

+0

Substring vs Substr - SO不會接受3個字符的編輯,所以我不能只是改變它。否則 - 是的,上述確實有效。然而它並沒有解決原始問題如何(或不可能)訪問由分割函數生成的元素。不錯的解決方案,但實際問題和巧妙使用IndexOf - 我已經忘記了這一點! –

+0

謝謝 - 修正了錯字。我的腦海裏語言太多!用MS SQL進行測試,似乎無論文檔如何,MS都在Linq to SQL/EF中實現了String.Split(),顯然是在客戶端處理的,而不是數組索引或其他數組處理(例如Last())。 。 – NetMage

+1

此外,顯然只有在最後選擇(例如試圖選擇一個分割導致沒有實現的SQL錯誤)。 – NetMage

0

我不明白爲什麼它會不索引操作工作,要麼,你的SQL似乎並沒有反映相同的LINQ代碼(有你使用LinqPad?),但我會建議,因爲你正在做.ToArray(),無論如何,將拆分/索引移動到客戶端:

var RMA_stops_all = (from rma in rDb.DistributionStopInformations 
        join line in rDb.DistributionLineItems on rma.UniqueIdNo equals line.UniqueIdNo 
        where line.RmaNumber != null 
        && 
        (line.DatetimeCreated > Convert.ToDateTime(dateToCheck_rma) && 
        line.DatetimeCreated < Convert.ToDateTime(dateToCheck_rma).AddDays(7)) 
        && rma.CustomerNo == TNGCustNo 
        select new 
        { 
         dtCreated = line.DatetimeCreated, 
         rma.UniqueIdNo, 
         line.RmaNumber, 
         line.RmaOriginalUniqueId, 
         line.ItemSequenceNo, 
         line.ItemNumber, 
         goodRMA_flag = line.RmaNumber.Contains("/078"), 
        }).AsEnumerable().Select(r => new { 
         r.dtCreated, 
         r.UniqueIdNo, 
         r.RmaNumber, 
         r.RmaOriginalUniqueId, 
         r.ItemSequenceNo, 
         r.ItemNumber, 
         r.goodRMA_flag, 
         rmaGood = r.RmaNumber.Split(new string[] { "/" }, StringSplitOptions.None)[1] 
        }); 

順便說一句,你不必重複字段/屬性名稱的簡單的訪問表達,所以我從原來的選擇刪除它們。另外,如果你可以忍受雙重間接,你可以在第二個選擇中加入r。