Прежде всего, я не думаю, что ваша оболочка будет работать - в вашей ETC.property
вы не можете взять обычную функцию в качестве аргумента и затем заключить ее в кавычки внутри ETC.property
. Вам нужно передать лямбда-функцию, как уже указано (и тип аргумента должен быть Expr<'a -> string>
:
entity |> ETC.property <@ fun z -> z.Path @>
|> finished
К вашему первоначальному вопросу - я думаю, что использование модуля с функциями-обертками - хороший вариант. Вы можете сделать синтаксис более приятным, передав представление объекта через конвейер, который задает свойства. С соответствующими определениями вы можете получить что-то вроде:
EF.entity<FileUpload> modelBuilder
|> EF.hasKey <@ fun z -> z.ID @>
|> EF.property <@ fun z -> z.Path @>
|> EF.property <@ fun z -> z.Extension @>
|> EF.toTable "Some"
Идея состоит в том, что у вас будет какой-то тип EntityInfo<'T>
, который оборачивает то, что вы получаете от вызова modelBuilder.Entity<'T>()
. Функции имеют типы типа:
EF.hasKey : Expr<'a -> 'b> -> EntityInfo<'T> -> EntityInfo<'T>
EF.toTable : string -> EntityInfo<'T> -> unit
Я намеренно использовал unit
как результат toTable
, потому что это, вероятно, что-то, что всегда нужно вызывать в любом случае (поэтому мы можем переместить его в конец и избежать явного ignore
). Другие функции просто задают свойства и затем возвращают исходный объект EntityInfo<'T>
.
Вы могли бы сделать это еще более причудливым и написать всю спецификацию как цитату. Например:
modelBuilder |> EF.entity<FileUpload> <@ fun z ->
EF.hasKey z.ID
EF.property z.Path
EF.property z.Extension
EF.toTable "Some" @>
Это не исполняемый код - функции будут просто фиктивными функциями. Хитрость в том, что вы можете обработать цитату и вызвать методы EF, основанные на этом. Тем не менее, это более сложная задача - вам придется довольно много обрабатывать цитаты, и это не слишком хорошо.