我有一些类型,它们都扩展了一个公共类型,并且这些类型是我的模型。
之后,我为每种模型类型都有相应的DAO类型,用于CRUD操作。
现在我需要一个函数,可以根据任何模型类型找到id,因此我创建了一个新类型来存放一些杂项函数。
问题在于我不知道如何对这些类型进行排序。目前,我的模型排在DAO之前,但我需要让 `DAOMisc` 排在 `CityDAO` 之前,而 `CityDAO` 又要排在 `DAOMisc` 之前,这是不可能的。
简单的方法是将此函数放在每个DAO中,仅涉及可以在其之前出现的类型,例如 `State` 比 `City` 先出现,因为 `State` 与 `City` 存在外键关系,所以杂项函数会非常简短。但是,这似乎不太合适,因此我不确定如何最好地解决这个问题。
以下是我的杂项类型,其中 `BaseType` 是我所有模型的公共类型。
这似乎是处理插入的最佳方法,非常通用,这正是我试图解决的当前问题。
更新:
我需要研究一下,看看是否可以在定义所有其他DAO之后将FindIdByType方法注入CommonDAO中,几乎就像是闭包一样。如果这是Java,我会使用AOP来获得我正在寻找的功能,但不确定如何在F#中实现。
最终更新:
在考虑我的方法后,我意识到它有致命的缺陷,因此我想出了另一种方法。
这就是我将进行插入的方式,并且我决定将这个想法放入每个实体类中,这可能是一个更好的想法。
之后,我为每种模型类型都有相应的DAO类型,用于CRUD操作。
现在我需要一个函数,可以根据任何模型类型找到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
这里有一个数据访问对象(dao)类型。CommonDAO
实际上包含了增删改查操作的代码,但这并不重要。
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方法注入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#可以做协变/逆变就好了,所以我不得不绕过这个限制。