我正在学习F#,并且为了变得更流畅,我正在将后端/数据访问层重新编写到当前正在使用带有ORM的C#的程序中。我正在使用SqlDataProvider类型提供程序(并且喜欢它btw)。
我在F#中对部分类类型的搜索没有出现任何有希望的结果。部分类的原因是为从Sql类型提供程序返回的数据库对象添加一些基本功能。到目前为止,我只是继承了从Sql类型提供程序返回的类型,并以这种方式添加功能。但是,当我从函数返回查询结果时,它返回基类,而不是派生类。
我不想使用反射来映射两个对象的属性,但我也不想返回“new fooObject {......}”并列出每个属性的每个属性时间我想创建一个新方法。
所以我在这里,在世界上所有人都是善的源头。我错过了一些我可以用于部分课堂创作的东西吗?有没有一种简单的方法(不使用反射)将返回的对象映射到派生对象?我完全错过了一些很棒的功能吗?
type DbContext = SqlDataConnection<ConnectionString="~">
//Database objects
type Address() =
//inheriting base class from SqlDataProvider
inherit DbContext.ServiceTypes.Address()
//Adding common functionality
member this.Add() =
use db = DbContext.GetDataContext()
db.Address.InsertOnSubmit this
db.DataContext.SubmitChanges()
member this.Remove() =
use db = DbContext.GetDataContext()
db.Address.DeleteOnSubmit this
db.DataContext.SubmitChanges()
member this.Update() =
use db = DbContext.GetDataContext()
let mutable old = query {for a in db.Address do
where (a.AddressId = this.AddressId)}
|> Seq.exactlyOne
old <- this
db.Address.Context.SubmitChanges()
//this method only returns the base object
static member GetAll() =
use db = DbContext.GetDataContext()
db.Address |> Seq.toList
//as does this one
static member Find addressId =
use db = DbContext.GetDataContext()
let add = new Address()
query {for a in db.Address do where (a.AddressId = addressId)}
|> Seq.exactlyOne
答案 0 :(得分:2)
F#使用type extensions执行此类操作:
type DbContext.ServiceTypes.Address with
member this.Add() =
use db = DbContext.GetDataContext()
db.Address.InsertOnSubmit this
db.DataContext.SubmitChanges()
member this.Remove() =
use db = DbContext.GetDataContext()
db.Address.DeleteOnSubmit this
db.DataContext.SubmitChanges()
member this.Update() =
use db = DbContext.GetDataContext()
let mutable old = query {for a in db.Address do
where (a.AddressId = this.AddressId)}
|> Seq.exactlyOne
old <- this
db.Address.Context.SubmitChanges()
请注意,只能从F#代码访问类型扩展(以此格式)。如果你需要与C#/ VB.Net可互操作的东西,你应该使用&#39; normal&#39;扩展方法:
[<Extension>]
type ExtraCSharpStyleExtensionMethodsInFSharp () =
[<Extension>]
static member this.Add (address:DbContext.ServiceTypes.Address) =
use db = DbContext.GetDataContext()
db.Address.InsertOnSubmit address
db.DataContext.SubmitChanges()
[<Extension>]
member this.Remove (address:DbContext.ServiceTypes.Address) =
use db = DbContext.GetDataContext()
db.Address.DeleteOnSubmit address
db.DataContext.SubmitChanges()
[<Extension>]
member this.Update (address:DbContext.ServiceTypes.Address) =
use db = DbContext.GetDataContext()
let mutable old = query {for a in db.Address do
where (a.AddressId = this.AddressId)}
|> Seq.exactlyOne
old <- address
db.Address.Context.SubmitChanges()
对于GetAll
和Find
方法,我很想创建一个包含GetAllAddresses
和FindAddress
等函数的模块。
总的来说,存储库模式在F#中有点尴尬。