2015-05-20 2 views
1

как вы преобразовываете список obj в тип int. Я пытаюсь добавить два списка, используя функцию карты ниже, но она не работает в списках obj.F резкие добавления списков

let query f= 
seq{ 
let cmd = new OleDbCommand("SELECT * FROM F"); 
let conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0; 
Data Source=D:\Users\df\Documents\Vfolio.accdb; 
Persist Security Info=False;") 

conn.Open() 
let DAdapt = new OleDbDataAdapter("SELECT * FROM F",conn) 
let DTab = new DataSet() 
let i= DAdapt.Fill(DTab) 
let rowCol = DTab.Tables.[0].Rows 
let rowCount = rowCol.Count 
for i in 0 .. (rowCount - 1) do 
      yield f (rowCol.[i]) 
    } 
let u= query(fun row -> row.[0]) 
let a= List.ofSeq u 
let v=query(fun row -> row.[1]) 
let b= List.ofSeq v 
let c = List.map2 (fun x y-> x + y) a b 

Ошибка сбщ: Тип «Obj» не поддерживает оператор «+»

+2

Вы можете попробовать использовать 'Seq.cast' в' пусть = List.ofSeq (Seq.cast и) 'и' пусть Ь = ' – Petr

ответ

5

Поскольку row.[i] возвращает тип obj, ваш u и v стать seq<obj>, и, таким образом, ваш a и b стали типа List<obj>, и поэтому у x и y есть тип obj, и, конечно же, вы не можете добавить два obj s, что и говорит вам компилятор.

Если вы уверены, что row.[0] и row.[1] являются числами некоторого вида, вы должны применить соответствующий оттенок, например:

let u= query(fun row -> row.[0] :?> int) 
let a= List.ofSeq u 
let v=query(fun row -> row.[1] :?> int) 
let b= List.ofSeq v 
let c = List.map2 (fun x y-> x + y) a b 

Вы можете применить этот бросок в других местах тоже, в зависимости от вашего вкуса и требования, например:

let c = List.map2 (fun x y-> (x :?> int) + (y :?> int)) a b 

Или:

let a= u |> Seq.cast<int> |> List.ofSeq 
let b= v |> Seq.cast<int> |> List.ofSeq 

Но мне нравится первый пример лучше всего, потому что он применяет бросок в самом раннем известном пункте и приводит к наименьшему количеству дополнительного кода.

Но будьте осторожны: если row.[0] не будет int во время выполнения, вы получите InvalidCastException.

P.S. В вашем List.map2 вызове, можно указать (+) непосредственно вместо окружив его дополнительной лямбда:

List.map2 (+) a b 

PPS Кроме того, мне кажется, что ваши List.ofSeq звонки расточительно для Seq также имеет map2:

let u = query(fun row -> row.[0] :?> int) 
let v = query(fun row -> row.[1] :?> int) 
let c = Seq.map2 (+) u v |> List.ofSeq 

PPPS Кроме того, вы заметили, что каждый из двух вызовов query создает свое собственное соединение с базой данных, команды, адаптера и набора данных? Вы намеревались это или вы имели в виду только одно соединение, а затем извлекали разные столбцы из результата? Если да, то вы должны вызывать только один раз query:

let c = query(fun row -> (row.[0] :?> int) + (row.[1] :?> int)) |> List.ofSeq 
+0

спасибо за объяснение, я просто понял, что некоторые из значений в запросе равны нулю. – HaagenDaz

Смежные вопросы