F#Sql Type Provider:如何访问

时间:2014-01-27 01:57:04

标签: f# type-providers

我使用TypeProvider来访问这样的数据:

type internal SqlConnection = 
    SqlEntityConnection<ConnectionString = 
        @"XXXXXXXXXX">

type FooRepository () =

    member x.GetFoo (Id) =
        let context = SqlConnection.GetDataContext()
        query {for foo in context.Foos do
                where (foo.Id = Id)
                select foo}

问题是我得到了这个:

  

“FooRepository”类型的可访问性低于

中使用的值,成员或类型“成员System.Linq.IQueryable”

我在SO here上看到同样的问题。

由于我想公开这种类型而我不喜欢SO上的解决方案,我尝试这样做:

SqlDataConnection<ConnectionString = 
    @"XXXXXXX">

问题是数据库在Azure Sql Server上,所以我得到了这个:

  

类型提供程序'Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders'报告错误:读取架构时出错。警告:SQM1012:无法从SqlServer中提取表'dbo.Foos。

有没有人知道如何解决这个问题?使用TP的最好的事情之一是我不需要明确定义类型 - 但看起来我将不得不这样做?唉

1 个答案:

答案 0 :(得分:3)

您确定您收到的错误是您在此处发布的错误吗?我的印象是 不太容易访问的类型应该是生成的数据库模式中的类型 (因为你将其标记为internal)。

我尝试通过编写一个使用Northwind数据库的简单库来重现您的错误:

open Microsoft.FSharp.Data.TypeProviders

type internal Nwind = SqlDataConnection<"Data Source=.\sqlexpress;Initial Catalog=Northwind;Integrated Security=True">
type NwindLibrary() = 
    let nw = Nwind.GetDataContext()
    member this.Products = nw.Products

我收到以下消息:

  

“产品”类型的可访问性低于值,成员或类型“成员Class1.Products:System.Data.Linq.Table”它在C:\ temp \ Library1 \ Library1 \ Library1.fs中使用9 17 LIBRARY1

这正是我所期待的 - 因为Nwind类型(由提供商生成)标记为internal。但是,NwindLibrary类型是公共的,属性Products(我定义的)返回类型IQueryable<Table<Nwind.ServiceTypes.Product>>的值。编译器错误在这里不是特别有用(因为它表示类型只返回Table),但问题是Nwind.ServiceTypes.Product是内部的,所以你不能在公共类型的公共属性中返回它

如果您将Nwind类型设为公开,那么它应该可以正常工作。如果您不想公开生成的类型,则必须将返回的值包装在自定义类型中。例如,即使您将类型保留为internal,下面的工作正常(返回元组而不是生成的类型):

member this.Products = 
  query { for p in mys.Products do
          select (p.ProductID, p.ProductName) }