Entity framework F#-使C#库更丰富”;“F”;
当您无法访问源代码时,让c#library更富F#ish的最佳方法是什么?在我看来,您似乎有两种选择:扩展方法或封装在模块中的函数 ……还是有一种更整洁、更不“黑”的方式来完成这样的任务 一个例子可以是EF代码优先 在我开始编写包装到模块中的函数之前:Entity framework F#-使C#库更丰富”;“F”;,entity-framework,f#,ef-code-first,Entity Framework,F#,Ef Code First,当您无法访问源代码时,让c#library更富F#ish的最佳方法是什么?在我看来,您似乎有两种选择:扩展方法或封装在模块中的函数 ……还是有一种更整洁、更不“黑”的方式来完成这样的任务 一个例子可以是EF代码优先 在我开始编写包装到模块中的函数之前: override x.OnModelCreating(modelBuilder:DbModelBuilder) = // ----------- FileUpload Configuration ----------- //
override x.OnModelCreating(modelBuilder:DbModelBuilder) =
// ----------- FileUpload Configuration ----------- //
// General
modelBuilder.Entity<FileUpload>()
.ToTable("Some")
|> ignore
// Key
modelBuilder.Entity<FileUpload>()
.HasKey(ToLinq(<@ fun z -> z.ID @>))
|> ignore
// Properties
modelBuilder.Entity<FileUpload>()
.Property(ToLinq(<@ fun z -> z.Path @>))
|> ignore
modelBuilder.Entity<FileUpload>()
.Property(ToLinq(<@ fun z -> z.Extension @>))
|> ignore
重写x.OnModelCreating(modelBuilder:DbModelBuilder)=
//------------文件上载配置-----------------//
//一般的
modelBuilder.Entity()
.ToTable(“部分”)
|>忽略
//钥匙
modelBuilder.Entity()
.HasKey(ToLinq(z.ID@>)
|>忽略
//性质
modelBuilder.Entity()
.Property(ToLinq(z.Path@>))
|>忽略
modelBuilder.Entity()
.属性(ToLinq(z.扩展@>)
|>忽略
及之后:
override x.OnModelCreating(modelBuilder:DbModelBuilder) =
let finished = ignore
// ----------- FileUpload Configuration ----------- //
let entity = modelBuilder.Entity<FileUpload>()
// General
entity
|> ETC.toTable "Some"
// Key
entity
|> ETC.hasKey(fun z -> z.ID)
|> finished
// Properties
entity
|> ETC.property(fun z -> z.Path)
|> finished
entity
|> ETC.property(fun z -> z.Extension)
|> finished
重写x.OnModelCreating(modelBuilder:DbModelBuilder)=
让完成=忽略
//------------文件上载配置-----------------//
让entity=modelBuilder.entity()
//一般的
实体
|>等等,一些
//钥匙
实体
|>ETC.hasKey(funz->z.ID)
|>完成
//性质
实体
|>ETC.property(funz->z.Path)
|>完成
实体
|>ETC.property(funz->z.Extension)
|>完成
后一个示例中使用的模块:
module ETC =
let property (expr:'a -> string) (cfg:EntityTypeConfiguration<'a>) =
cfg.Property(ToLinq(<@ expr @>))
let hasKey (expr:'a -> 'b) (cfg:EntityTypeConfiguration<'a>) =
cfg.HasKey(% expr)
let hasForeignKey (expr: 'a -> 'b) (cfg:DependentNavigationPropertyConfiguration<'a>) =
cfg.HasForeignKey(% expr)
let hasMany (expr: 'a -> ICollection<'b>) (cfg:EntityTypeConfiguration<'a>) =
cfg.HasMany(% expr)
let hasRequired (expr: 'a -> 'b) (cfg:EntityTypeConfiguration<'a>) = cfg.HasRequired(ToLinq(<@ expr @>))
let withRequired (expr: 'a -> 'a) (cfg:ManyNavigationPropertyConfiguration<'a,'a>) =
cfg.WithRequired(% expr)
let willCascadeOnDelete (cfg:CascadableNavigationPropertyConfiguration) =
cfg.WillCascadeOnDelete()
let isMaxLength(cfg:StringPropertyConfiguration) =
cfg.IsMaxLength()
let toTable (s:string) (cfg:EntityTypeConfiguration<'a>) =
cfg.ToTable s
modelBuilder |> EF.entity<FileUpload> <@ fun z ->
EF.hasKey z.ID
EF.property z.Path
EF.property z.Extension
EF.toTable "Some" @>
模块等=
let属性(expr:'a->string)(cfg:EntityTypeConfiguration'b)(cfg:EntityTypeConfiguration'b)(cfg:DependentNavigationPropertyConfiguration ICollection)=
cfg.HasMany(%expr)
let hasRequired(expr:'a->'b)(cfg:EntityTypeConfiguration'a)(cfg:ManyNavigationPropertyConfiguration)=
cfg.WithRequired(%expr)
让willCascadeOnDelete(cfg:CascadableNavigationPropertyConfiguration)=
cfg.WillCascadeOnDelete()
设isMaxLength(cfg:StringPropertyConfiguration)=
cfg.IsMaxLength()
让toTable(s:string)(cfg:EntityTypeConfiguration首先,我认为您的包装器不会起作用-在ETC.property
中,您不能将普通函数作为参数,然后在ETC.property
中引用它。您需要按照已经引用的方式传递lambda函数(并且参数的类型必须是expr为什么不使用F#编写它,将它公开给C#程序,而不用担心它。
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"
EF.hasKey : Expr<'a -> 'b> -> EntityInfo<'T> -> EntityInfo<'T>
EF.toTable : string -> EntityInfo<'T> -> unit
modelBuilder |> EF.entity<FileUpload> <@ fun z ->
EF.hasKey z.ID
EF.property z.Path
EF.property z.Extension
EF.toTable "Some" @>