У меня есть несколько типов, которые расширяют общий тип, и это мои модели.
Затем у меня есть типы DAO для каждого типа модели для операций CRUD.
Теперь мне нужна функция, которая позволит мне найти идентификатор для любого типа модели, поэтому я создал новый тип для некоторых других функций.
Проблема в том, что я не знаю, как заказать эти типы. В настоящее время у меня есть модели до 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
заключается в том, что я хочу найти идентификатор для отношения внешнего ключа, чтобы я мог установить значение в моей модели и затем сделать так, чтобы функции CRUD выполняли операции со всей правильной информацией. Итак, City
нужен идентификатор для имени штата, поэтому я бы получил имя штата, поместил его в тип state
, а затем вызвал эту функцию, чтобы получить идентификатор для этого состояния, так что моя вставка города также будет включать идентификатор для внешнего ключа.
Похоже, что это лучший подход, очень общий способ обработки вставок, что является текущей проблемой, которую я пытаюсь решить.
UPDATE:
Мне нужно исследовать и посмотреть, смогу ли я каким-то образом внедрить метод FindIdByType в CommonDAO после того, как все другие DAO определены, почти как если бы это было закрытием. Если бы это была 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 # мог делать ко / противоречие, поэтому мне пришлось обойти это ограничение.