Linq-to-SQL查询中的String.Split?

我有一个包含nvarchar列的数据库表,如下所示:

1|12.6|18|19 

我有一个具有Decimal []属性的Business Object。

我的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(); 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。

您需要先通过调用.AsEnumerable()强制select子句在客户端上运行:

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

您不需要使用临时列表:

 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(); 

不幸的是,你使用的IQueryable(Linq to SQL)不支持Splitfunction。

在这种情况下,你真的只剩下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) ; 

您不能使用拆分,但在这种情况下,您可以执行以下操作:

 // 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