Problema al determinar cómo ordenar tipos F # debido a referencias circulares

Tengo algunos tipos que extienden un tipo común, y estos son mis modelos.

Luego tengo tipos DAO para cada tipo de modelo para operaciones CRUD.

Ahora tengo una necesidad de una función que me permita encontrar una identificación dada cualquier tipo de modelo, así que creé un nuevo tipo para algunas funciones misceláneas.

El problema es que no sé cómo ordenar estos tipos. Actualmente tengo modelos antes de dao, pero de alguna manera necesitoDAOMisc antes deCityDAO yCityDAO antes deDAOMisc, que no es posible.

El enfoque simple sería poner esta función en cada DAO, refiriéndose solo a los tipos que pueden venir antes, entonces,State viene antesCity comoState tiene una relación de clave extranjera conCity, por lo que la función miscelánea sería muy corta. Pero, esto me parece incorrecto, por lo que no estoy seguro de cómo abordarlo mejor.

Aquí está mi tipo misceláneo, dondeBaseType Es un tipo común para todos mis modelos.

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

Aquí hay un tipo de dao.CommonDAO en realidad tiene el código para las operaciones CRUD, pero eso no es importante aquí.

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
    )

Este es mi tipo de modelo:

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);]

El propósito de estoFindIdByType La función es que quiero encontrar la identificación para una relación de clave externa, para poder establecer el valor en mi modelo y luego hacer que las funciones CRUD realicen las operaciones con toda la información correcta. Entonces,City necesita la identificación para el nombre del estado, así que obtendría el nombre del estado, lo pondría en elstate escriba, luego llame a esta función para obtener la identificación de ese estado, por lo que mi inserción de ciudad también incluirá la identificación de la clave externa.

Este parece ser el mejor enfoque, de una manera muy genérica para manejar insertos, que es el problema actual que estoy tratando de resolver.

ACTUALIZAR:

Necesito investigar y ver si de alguna manera puedo inyectar el método FindIdByType en CommonDAO después de que se hayan definido todos los otros DAO, casi como si fuera un cierre. Si esto fuera Java, usaría AOP para obtener la funcionalidad que estoy buscando, sin saber cómo hacerlo en F #.

Actualización final:

Después de pensar en mi enfoque, me di cuenta de que tenía un defecto fatal, así que se me ocurrió un enfoque diferente.

Así es como haré una inserción, y decidí poner esta idea en cada clase de entidad, que probablemente sea una mejor idea.

member self.Insert(user:CityType) =
    let fk1 = [(StateDAO().Retrieve ((user.ToFKValuesList.Head :?> StateType), list.Empty)).Head.Id]
    self.Insert (user, fk1)

No he empezado a usar elfklist todavía, pero esint list y sé qué nombre de columna va con cada uno, así que solo necesito hacerinner join para selecciones, por ejemplo.

Este es el inserto de tipo base que se generaliza:

member self.Insert(user:'a, fklist) =
    self.ExecNonQuery (self.BuildUserInsertQuery user)

Sería bueno si F # pudiera hacer co / contra-varianza, por lo que tuve que evitar esa limitación.

Respuestas a la pregunta(4)

Su respuesta a la pregunta