2010-11-29 60 views
8

我有一個包含這樣一個nvarchar列數據庫表:Linq-To-SQL查詢中的String.Split?

1|12.6|18|19 

我有,有一個十進制數[]屬性的業務對象。

我的LINQ查詢看起來是這樣的:

var temp = from r in db.SomeTable select new BusinessObject { 
    // Other BusinessObject Properties snipped as they are straight 1:1 
    MeterValues = r.MeterValues.Split('|').Select(Decimal.Parse).ToArray() 
}; 
var result = temp.ToArray(); 

這將引發NotSupportedException異常:Method 'System.String[] Split(Char[])' has no supported translation to SQL.

這有點兒吮吸:)有沒有什麼辦法可以做到這一點,而無需一個字符串屬性添加到業務對象或選擇一個匿名類型,然後迭代它?

我目前的 「解決方案」 是:

var temp = from r in db.SomeTable select new { 
    mv = r.MeterValues, 
    bo = new BusinessObject { // all the other fields } 
}; 
var result = new List<BusinessObject>(); 
foreach(var t in temp) { 
    var bo = t.bo; 
    bo.MeterValues = t.mv.Split('|').Select(Decimal.Parse).ToArray(); 
    result.Add(bo); 
} 
return result.ToArray(); // The Method returns BusinessObject[] 

這是有點難看,雖然,與臨時列表。

我試過增加一個let mv = r.MeterValues.Split('|').Select(Decimal.Parse).ToArray()但基本上導致相同的NotSupportedException。

這是.net 3.5SP1如果有問題。

回答

6

您需要通過調用.AsEnumerable()首先迫使select子句在客戶端上運行:

var result = db.SomeTable.AsEnumerable().Select(r => new BusinessObject { 
    ... 
    MeterValues = r.MeterValues.Split('|').Select(Decimal.Parse).ToArray() 
}).ToList(); 
+1

這是否選擇整個SomeTable表? – 2010-11-29 00:34:30

1

不幸的是它的你使用的是不支持拆分功能的IQueryable(LINQ到SQL)。

在這種情況下,您確實只剩下IEnumerable(Linq to Objects)支持。你第二代碼片段是你需要做什麼,或類似的東西...

var temp = (from r in db.SomeTable select new { 
    mv = r.MeterValues, 
    bo = new BusinessObject { // all the other fields } 
}).AsEnumerable().Select(blah, blah) ; 
2

你並不需要使用的臨時列表:

var query = from r in db.SomeTable 
      select new 
      { 
       r.Id, 
       r.Name, 
       r.MeterValues, 
       ... 
      }; 

var temp = from x in query.AsEnumerable() 
      select new BusinessObject 
      { 
       Id = x.Id, 
       Name = x.Name, 
       MeterValues = x.mv.Split('|').Select(Decimal.Parse).ToArray(), 
       ... 
      }; 

return temp.ToArray(); 
2

不能使用分裂,但在這種情況下,您可以執行以下操作:

// Database value is 1|12.6|18|19 

string valueToFind = "19"; 

var temp = from r in db.SomeTable.Where(r => ("|" + r.MeterValues + "|").Contains("|" + valueToFind + "|")); 

該代碼添加外管(|)對查詢中飛的數據庫值,所以你可以做開始,中間和結束值的字符串相匹配。

例如,上面的代碼查找「| 19 |」在「| 1 | 12.6 | 18 | 19 |」中找到並且有效。這將適用於任何其他valueToFind