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

时间:2010-11-29 00:26:13

标签: c# .net linq linq-to-sql

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

1|12.6|18|19

我有一个具有Decimal []属性的业务对象。

我的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。

4 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分: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 :(得分: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 + "|"));

此代码在查询中动态地将外部管道(|)添加到数据库值,以便您可以对字符串执行开始,中间和结束值匹配。

例如,上面的代码查找&#34; | 19 |&#34;在&#34; | 1 | 12.6 | 18 | 19 |&#34;中,找到并且有效。这适用于任何其他 valueToFind

答案 3 :(得分:1)

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

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