F# - 合并模块?

时间:2011-04-24 14:26:47

标签: entity-framework f# ef-code-first

我正在为F#开发一个实体框架代码第一个包装器,我一直在想我是否应该将所有模块合并为一个。

看看这个:

module ManyNavProperty =
    let withMany (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithMany()
    let withSeq expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithSeq expr
    let withList expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithList expr
    let withArray expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithArray expr
    let withOptional (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithOptional()
    let withOptionalProperty expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithOptional expr
    let withRequired (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithRequired()
    let withRequiredProperty expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithRequiredProperty expr

module DependentNavProperty =
    let hasForeignKey expr (cfg:DependentNavPropertyInfo<'a>) = cfg.HasForeignKey expr

module CascadableNavProperty =
    let willCascadeOnDelete b (cfg:CascadableNavPropertyInfo) = cfg.WillCascadeOnDelete b

module EF =
    let entity<'a when 'a : not struct> (cfg:DbModelBuilder) = EntityInfo<'a>(cfg.Entity<'a>())
    let hasKey expr (cfg:EntityInfo<'a>) = cfg.HasKey expr
    let hasSeq expr (cfg:EntityInfo<'a>) = cfg.HasSeq expr
    let hasList expr (cfg:EntityInfo<'a>) = cfg.HasList expr 
    let hasArray expr (cfg:EntityInfo<'a>) = cfg.HasArray expr
    let hasOptional expr (cfg:EntityInfo<'a>) = cfg.HasOptional expr
    let hasRequired expr (cfg:EntityInfo<'a>) = cfg.HasRequried expr
    let toTable s (cfg:EntityInfo<'a>) = cfg.ToTable s

这需要我调用代码:

override x.OnModelCreating (mb:DbModelBuilder) =
    let finished = ignore
    let entity = EF.entity<Author> mb

    entity
    |> EF.hasSeq <@ fun z -> z.Books @>
        |> ManyNavProperty.withRequiredProperty <@ fun z -> z.Author @>
            |> DependentNavProperty.hasForeignKey <@ fun z -> z.AuthorId @>
                |> CascadableNavProperty.willCascadeOnDelete true
    |> finished

使用这么多模块会让用户感到困惑吗? - 我应该将它们全部放入一个模块中,还是会破坏用户的概述?

所有功能都放在同一个模块中的示例:

override x.OnModelCreating (mb:DbModelBuilder) =
    let finished = ignore
    let entity = EF.entity<Author> mb

    entity
    |> EF.hasSeq <@ fun z -> z.Books @>
        |> EF.withRequiredProperty <@ fun z -> z.Author @>
            |> EF.hasForeignKey <@ fun z -> z.AuthorId @>
                |> EF.willCascadeOnDelete true
    |> finished

1 个答案:

答案 0 :(得分:7)

这是一个棘手的设计问题。

通常,F#库倾向于将一个类型(例如list<T>seq<T>)的函数分组到一个单独的模块中,其名称与类型相同(例如List.xyz和{ {1}})。这适用于常见类型,因为用户可以学习如何查找函数。

但是,对于不太常见的类型(例如您自己的库),发现这些模块可能有点困难(特别是如果未明确创建类型(但是由于某些调用而获得)。拥有一个模块名称,然后使用Seq.xyz来探索它是非常强大的。

我可能会建议使用嵌套模块。类似的东西:

.

然后,用户可以从module EF = // common functions module Cascadable = // CascadableNavProperty functions module Many = // etc. 开始查找所有内容。他们写的是:

EF