String.Split в запросе Linq-To-SQL? - PullRequest
9 голосов
/ 29 ноября 2010

У меня есть таблица базы данных, которая содержит такой столбец 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 ]

6 голосов
/ 29 ноября 2010

Необходимо принудительно запустить предложение select на клиенте, сначала вызвав .AsEnumerable():

var result = db.SomeTable.AsEnumerable().Select(r => new BusinessObject {
    ...
    MeterValues = r.MeterValues.Split('|').Select(Decimal.Parse).ToArray()
}).ToList();
3 голосов
/ 23 января 2017

Вы не можете использовать разделение, но в этом сценарии вы можете сделать следующее:

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

2 голосов
/ 29 ноября 2010

Вам не нужно использовать временный список:

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();
1 голос
/ 29 ноября 2010

К сожалению, используемый вами 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) ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...