我有一些扩展通用类型的类型,这些是我的模型。
然后,我为 CRUD 操作的每种模型类型提供了 DAO 类型。
我现在需要一个函数,它可以让我找到给定任何模型类型的 id,所以我为一些杂项函数创建了一个新类型。
问题是我不知道如何订购这些类型。目前我在 dao 之前有模型,但我不知何故需要 DAOMisc
之前 CityDAO
和 CityDAO
之前 DAOMisc
,这是不可能的。
简单的方法是把这个函数放在每个 DAO 中,只引用它之前的类型,所以,State
出现在 City
之前如State
与 City
有外键关系,所以杂项函数会很短。但是,这让我觉得是错误的,所以我不确定如何最好地解决这个问题。
这是我的杂项类型,其中BaseType
是我所有模型的通用类型。
type DAOMisc =
member internal self.FindIdByType item =
match(item:BaseType) with
| :? StateType as i ->
let a = (StateDAO()).Retrieve i
a.Head.Id
| :? CityType as i ->
let a = (CityDAO()).Retrieve i
a.Head.Id
| _ -> -1
这是一种道类型。
CommonDAO
实际上有 CRUD 操作的代码,但这在这里并不重要。type CityDAO() =
inherit CommonDAO<CityType>("city", ["name"; "state_id"],
(fun(reader) ->
[
while reader.Read() do
let s = new CityType()
s.Id <- reader.GetInt32 0
s.Name <- reader.GetString 1
s.StateName <- reader.GetString 3
]), list.Empty
)
这是我的模型类型:
type CityType() =
inherit BaseType()
let mutable name = ""
let mutable stateName = ""
member this.Name with get() = name and set restnameval=name <- restnameval
member this.StateName with get() = stateName and set stateidval=stateName <- stateidval
override this.ToSqlValuesList = [this.Name;]
override this.ToFKValuesList = [StateType(Name=this.StateName);]
这样做的目的
FindIdByType
功能是我想找到外键关系的 id,所以我可以在我的模型中设置值,然后让 CRUD 函数使用所有正确的信息进行操作。所以,City
需要州名的 id,所以我会得到州名,将其放入 state
键入,然后调用此函数以获取该州的 id,因此我的城市插入还将包括外键的 id。这似乎是最好的方法,以一种非常通用的方式处理插入,这是我正在尝试解决的当前问题。
更新:
在定义了所有其他 DAO 之后,我需要研究并查看是否可以以某种方式将 FindIdByType 方法注入(inject) CommonDAO,就好像它是一个闭包一样。如果这是 Java,我会使用 AOP 来获得我正在寻找的功能,但不确定如何在 F# 中执行此操作。
最后更新:
在考虑了我的方法后,我意识到它有致命的缺陷,所以我想出了一个不同的方法。
这就是我将如何进行插入,我决定将这个想法放入每个实体类中,这可能是一个更好的想法。
member self.Insert(user:CityType) =
let fk1 = [(StateDAO().Retrieve ((user.ToFKValuesList.Head :?> StateType), list.Empty)).Head.Id]
self.Insert (user, fk1)
我还没有开始使用
fklist
然而,但它是int list
我知道每个列的名称,所以我只需要做inner join
例如,对于选择。这是泛化的基本类型插入:
member self.Insert(user:'a, fklist) =
self.ExecNonQuery (self.BuildUserInsertQuery user)
如果 F# 可以做协方差,那就太好了,所以我必须解决这个限制。
最佳答案
这个例子与我在函数式编程中所习惯的相差甚远。但是对于相互递归类型的排序问题,有一个标准的解决方案:使用类型参数,做两级类型。我将在 OCaml(一种相关语言)中给出一个简单的示例。我不知道如何将这个简单的例子翻译成你正在使用的可怕的类型函数。
这是不起作用的:
type misc = State of string
| City of city
type city = { zipcode : int; location : misc }
以下是使用两级类型修复它的方法:
type 'm city' = { zipcode : int; location : 'm }
type misc = State of string
| City of misc city'
type city = misc city'
这个例子是 OCaml,但也许你可以推广到 F#。希望这可以帮助。
关于f# - 由于循环引用,确定如何订购 F# 类型的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2854145/