我有一个函数可以创建一个select where子句,但是现在一切都必须是一个字符串。
我想查看传入的变量并确定它是什么类型然后正确处理它。
例如,数值周围没有单引号,选项类型将为null或具有某个值,布尔值实际上为零或一。
member self.BuildSelectWhereQuery (oldUser:'a) = //'
let properties = List.zip oldUser.ToSqlValuesList sqlColumnList
let init = false, new StringBuilder()
let anyChange, (formatted:StringBuilder) =
properties |> Seq.fold (fun (anyChange, sb) (oldVal, name) ->
match(anyChange) with
| true -> true, sb.AppendFormat(" AND {0} = '{1}'", name, oldVal)
| _ -> true, sb.AppendFormat("{0} = '{1}'", name, oldVal)
) init
formatted.ToString()
这是一个实体:
type CityType() =
inherit BaseType()
let mutable name = ""
let mutable stateId = 0
member this.Name with get() = name and set restnameval=name <- restnameval
member this.StateId with get() = stateId and set stateidval=stateId <- stateidval
override this.ToSqlValuesList = [this.Name; this.StateId.ToString()]
因此,如果name
除了字符串之外还有其他值,或者stateId
可以是可选的,那么我需要进行两项更改:
我在想我需要一个新的函数来处理,但是最好的FP方法是什么,而不是使用类似typeof
的东西?
答案 0 :(得分:3)
您可以在匹配中使用类型测试模式。这会满足你的需求吗?
let f (x : obj) =
match x with
| :? int -> "int"
| :? string -> "string"
| :? bool -> "bool"
| _ -> "who knows?"
答案 1 :(得分:2)
我认为一种明确的功能方法是定义一种数据类型,代表您需要处理的各种(更复杂的情况)。您提到值可能是可选的,您需要区分数值和文本值(对于编码为SQL)。
您可以定义一个有区别的联合(如果您还有其他情况需要处理,那么定义可能会更复杂一些):
type SqlValue =
| Missing
| Numeric of string
| Textual of string
请注意,Textual
情况也带有string
,因为我假设生成该值的客户端负责将其转换为字符串 - 这只是您的SQL查询生成器的信息(这样它知道是否需要添加引号。
您的ToSqlValuesList
成员会返回值string & SqlValue
的列表,例如,可以使用以下列表表示示例产品:
columns = [ "Name"; "Price"; "Description" ]
values = [ Textual("Tea"); Numeric(10); Missing ]
在生成SQL查询的代码中,您将使用模式匹配来处理所有不同的情况(最重要的是,编码字符串以避免SQL注入,以防值为Textual
: - ))。< / p>
编辑您需要在每个客户端实现从特定数据类型到SqlValue
表示的转换。但是,这可以通过编写实用程序类型(使用成员可以重载的事实)来简化:
type SqlValue with
static member From(a:int) = Numeric(a.ToString())
static member From(a:int option) =
match a with None -> Missing | Some(n) -> SqlValue.From(n)
// ... similarly for other types
在ToSqlValuesList
的实现中,您可以编写SqlValue.From(description)
并自动处理详细信息。
更复杂的方法是使用.NET属性注释表示数据实体的类型的公共成员,并使用Reflection在运行时提取值(及其类型)。这是更先进的,但相当优雅(在Don Syme的专家F#书中有一个很好的例子)