Ho alcuni tipi che estendono un tipo comune e questi sono i miei modelli.Problema nel determinare come ordinare i tipi F # a causa di riferimenti circolari
Quindi ho i tipi DAO per ogni tipo di modello per le operazioni CRUD.
Ora ho bisogno di una funzione che mi consenta di trovare un ID dato qualsiasi tipo di modello, quindi ho creato un nuovo tipo per alcune funzioni varie.
Il problema è che non so come ordinare questi tipi. Attualmente ho modelli prima di Dao, ma ho in qualche modo bisogno di DAOMisc
prima di CityDAO
e CityDAO
prima di DAOMisc
, che non è possibile.
L'approccio semplice sarebbe quello di mettere questa funzione in ogni DAO, riferendosi ai soli tipi che possono venire prima, così, State
viene prima City
come State
ha una relazione di chiave esterna con City
, quindi la funzione ausiliaria sarebbe molto corto. Ma questo mi sembra sbagliato, quindi non sono sicuro di come affrontarlo al meglio.
Ecco il mio tipo miscellaneo, dove BaseType
è un tipo comune per tutti i miei modelli.
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
Ecco un tipo dao. CommonDAO
ha effettivamente il codice per le operazioni CRUD, ma qui non è importante.
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
)
Questo è il mio tipo di modello:
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);]
Lo scopo di questa funzione FindIdByType
è che voglio trovare l'id di una relazione di chiave esterna, quindi posso impostare il valore nel mio modello e quindi fare in modo che le funzioni CRUD eseguano le operazioni con tutte le informazioni corrette. Quindi, City
ha bisogno dell'ID per il nome dello stato, quindi dovrei ottenere il nome dello stato, inserirlo nel tipo state
, quindi chiamare questa funzione per ottenere l'id per quello stato, quindi la mia inserzione di città includerà anche l'id per l'estero chiave.
Questo sembra essere l'approccio migliore, in un modo molto generico per gestire gli inserti, che è il problema corrente che sto cercando di risolvere.
UPDATE:
ho bisogno di ricerca e vedere se posso in qualche modo iniettare il metodo FindIdByType nella CommonDAO dopo sono stati definiti tutti gli altri DAO, quasi come se si tratta di una chiusura. Se questo fosse Java, userei AOP per ottenere la funzionalità che sto cercando, non certo come farlo in F #.
aggiornamento finale:
Dopo pensare al mio approccio che ho capito che era fatalmente difettosa, così mi si avvicinò con un approccio diverso.
In questo modo inserirò un inserto e ho deciso di inserire questa idea in ogni classe di entità, che è probabilmente un'idea migliore.
member self.Insert(user:CityType) =
let fk1 = [(StateDAO().Retrieve ((user.ToFKValuesList.Head :?> StateType), list.Empty)).Head.Id]
self.Insert (user, fk1)
non ho iniziato ad utilizzare il fklist
ancora, ma è int list
e so che nome della colonna va con ciascuno di essi, quindi ho solo bisogno di fare inner join
per seleziona, per esempio.
Questo è il tipo di base inserto che è generalizzato:
member self.Insert(user:'a, fklist) =
self.ExecNonQuery (self.BuildUserInsertQuery user)
Sarebbe bello se F # poteva fare co/contra-varianza, quindi ho dovuto aggirare questa limitazione.
Vedi anche http: // StackOverflow .com/questions/1378575/f-forward-type-declarations – Brian
@Brian - Fino a quando ho pensato a questa altra domanda non ho considerato solo l'utilizzo e tra diversi tipi. Sembra un trucco per un design imperfetto, da parte mia, ma penso che sia l'approccio migliore. –