首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从基础扩展数据库对象/下传

从基础扩展数据库对象/下传
EN

Stack Overflow用户
提问于 2014-11-11 04:23:21
回答 1查看 123关注 0票数 1

我正在学习F#,为了变得更流利,我正在重写一个后端/数据访问层,这个程序目前正在使用C#和ORM。我正在使用SqlDataProvider类型提供程序(顺便说一句,我也很喜欢它)。

我在F#中搜索的部分类类型没有显示出任何有希望的结果。部分类的原因是要向从Sql类型提供程序返回的数据库对象添加一些基本功能。到目前为止,我只是从Sql类型提供程序返回的类型继承,并以这种方式添加功能。但是,当我从函数返回查询结果时,它返回的是基类,而不是派生类。

我不想使用反射在两个对象的属性之间映射,但我也不希望在每次创建新方法时返回一个“新fooObject {. }”并列出每个属性。

所以我在这里,在这个世界上一切都是美好的源头。我是不是遗漏了一些可以用于部分类创建的东西?是否有一种简单的方法(不使用反射)将返回的对象映射到派生对象?我是不是完全错过了一些很棒的功能?

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-11 10:18:41

F#用类型扩展做这种事

代码语言:javascript
复制
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进行互操作,则应该使用“正常”扩展方法:

代码语言:javascript
复制
[<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()

至于GetAllFind方法,我很想创建一个功能像GetAllAddressesFindAddress这样的模块。

总的来说,存储库模式在F#中有点笨拙。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26857424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档