F# type confusion - I'm sure I'm getting the value I need but the compiler, at run time, does not agree -
i've got nice qc testing tool access via vb existing setup. tool give me strong typed access tables without making new classes etc. 1 of tables, sadly, uses commalist instead of child tables.
this commalist causing me issues. code below, in theory, should split row.commalist , tell me if given number lies within.
i able output value commalistvalues bit - it's bool. feed parameters given , compiler seems happy.
why won't it, @ run time, use boolean criteria? i've got mental block guess - don't use f# routinely i'm wanting - unfortunately these niggles eat time.
can help?
edited requested. typical values commalist sample be:"234,132,554,6344,243,677"
module quality_control open system open system.collections.generic open system.data open system.data.linq open microsoft.fsharp.data.typeproviders open microsoft.fsharp.linq type dbschema = sqldataconnection<"data source=someserver;initial catalog=sqldb;user id=sa;password=######"> let db = dbschema.getdatacontext() type qualitychecks(singleidtomatch) = let questionlist ( q : string, singleidtomatch: string) = q.split [| ','|] |> fun x -> x.equals(singleidtomatch) member x.matchid= query{ row in db.sometablewithcommalistcolumn (questionlist(row.commalistvalue, system.convert.tostring(singleidtomatch))) select row}
i following error:
system.argumentexception occurred hresult=-2147024809 message=the argument 'value' wrong type. expected 'system.func2[system.tuple
2[system.string,system.string],system.boolean]'. actual 'system.boolean'. source=system.data.linq stacktrace: @ system.data.linq.sqlclient.sqlmethodcall.set_object(sqlexpression value) @ system.data.linq.sqlclient.sqlmethodcall..ctor(type clrtype, providertype sqltype, methodinfo method, sqlexpression obj, ienumerable1 args, expression sourceexpression) @ system.data.linq.sqlclient.sqlfactory.methodcall(methodinfo method, sqlexpression obj, sqlexpression[] args, expression sourceexpression) @ system.data.linq.sqlclient.queryconverter.visitmethodcall(methodcallexpression mc) @ system.data.linq.sqlclient.queryconverter.visitinner(expression node) @ system.data.linq.sqlclient.queryconverter.visitexpression(expression exp) @ system.data.linq.sqlclient.queryconverter.visitwhere(expression sequence, lambdaexpression predicate) @ system.data.linq.sqlclient.queryconverter.visitsequenceoperatorcall(methodcallexpression mc) @ system.data.linq.sqlclient.queryconverter.visitmethodcall(methodcallexpression mc) @ system.data.linq.sqlclient.queryconverter.visitinner(expression node) @ system.data.linq.sqlclient.queryconverter.convertouter(expression node) @ system.data.linq.sqlclient.sqlprovider.buildquery(expression query, sqlnodeannotations annotations) @ system.data.linq.sqlclient.sqlprovider.system.data.linq.provider.iprovider.execute(expression query) @ system.data.linq.dataquery
1.system.collections.generic.ienumerable.getenumerator() @ removed project details innerexception:
the type provider attempts convert query expression sql, isn't able translate questionlist()
call where
clause. simple solution change matchid()
this:
member x.matchid= let idstring = singleidtomatch.tostring() query { row in db.sometablewithcommalistcolumn (row.commalistvalue.endswith("," + idstring) || row.commalistvalue.startswith(idstring + ",") || row.commalistvalue.contains("," + idstring + ",")) select row }
this executes following sql:
select [t0].[commalistvalue] [dbo].[sometablewithcommalistcolumn] [t0] ([t0].[commalistvalue] @p0) or ([t0].[commalistvalue] @p1) or ([t0].[commalistvalue] @p2)
(the parameters include appropriate wildcards give results equivalent f# code in query expression)
composition
if need compose multiple where
clauses, can chain query expressions, this:
let withatleast10characters (q : linq.iqueryable<dbschema.servicetypes.sometablewithcommalistcolumn>) = query { row in q (row.commalistvalue.length >= 10) select row } let result = qualitychecks.matchid |> withatleast10characters
when evaluated, you'll sql looks this:
select [t0].[commalistvalue] [dbo].[sometablewithcommalistcolumn] [t0] (datalength([t0].[commalistvalue]) >= @p0) , (([t0].[commalistvalue] @p1) or ([t0].[commalistvalue] @p2) or ([t0].[commalistvalue] @p3))
Comments
Post a Comment