代码之家  ›  专栏  ›  技术社区  ›  Joel Mueller

没有元数据的实体SQL?

  •  2
  • Joel Mueller  · 技术社区  · 14 年前

    对于编译时未知的数据库模式,我需要针对各种数据库提供程序生成SQL查询。我看到Entity Framework已经做了大量的工作,提供了一个名为Entity SQL的SQL方言,它在执行之前被翻译成原生SQL,我希望在某种程度上利用它。

    理想情况下,我只想生成ESQL,运行它,并获得一个 IDataReader 实体框架则担心特定于提供者的细节。然而,似乎没有一种方法来创建 EntityConnection 没有以SSDL、CSDL和MSL文件的形式提供元数据,直到运行时我才知道数据库模式。

    谢谢你的时间。

    更新

    在飞行中,没有写任何文件。结果,我能做到我所希望的。现在,我需要做的就是找出如何从生成的元数据中提取有关可用表/视图的信息以供自己使用。

    #r "System.Data.Entity"
    #r "System.Data.Entity.Design"
    #r "System.Transactions"
    
    open System
    open System.IO
    open System.Data
    open System.Data.EntityClient
    open System.Data.Entity.Design
    open System.Data.Mapping
    open System.Data.Metadata.Edm
    open System.Data.SqlClient
    open System.Text
    open System.Xml
    
    let dbName = "Northwind"
    let cnstr = sprintf "Server=.;Database=%s;Integrated Security=SSPI" dbName
    let provider = "System.Data.SqlClient"
    
    let mslText = StringBuilder()
    let mslWriter = XmlWriter.Create(mslText)
    
    let schemaGen = EntityStoreSchemaGenerator(provider, cnstr, dbName)
    schemaGen.GenerateStoreMetadata() |> ignore
    
    let modelGen = EntityModelSchemaGenerator(schemaGen.EntityContainer)
    modelGen.GenerateMetadata() |> ignore
    modelGen.WriteStorageMapping(mslWriter)
    mslWriter.Close()
    
    let mslReader = XmlReader.Create(new StringReader(mslText.ToString()))
    
    let ssdlCollection = schemaGen.StoreItemCollection
    let csdlCollection = modelGen.EdmItemCollection
    let mslCollection = StorageMappingItemCollection(csdlCollection, ssdlCollection, [| mslReader |])
    
    let mdw = MetadataWorkspace()
    mdw.RegisterItemCollection(csdlCollection)
    mdw.RegisterItemCollection(ssdlCollection)
    mdw.RegisterItemCollection(mslCollection)
    
    let sqlCn = new SqlConnection(cnstr)
    let cn = new EntityConnection(mdw, sqlCn)
    let cmd = cn.CreateCommand()
    cmd.CommandText <- sprintf "SELECT p.ProductName FROM %sContext.Products AS p" dbName
    cn.Open()
    let reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)
    
    while reader.Read() do
        printfn "%A" reader.["ProductName"]
    
    reader.Close()
    cn.Close()
    sqlCn.Close()
    
    1 回复  |  直到 4 年前
        1
  •  1
  •   Alex James    14 年前

    来帮你开始这个 This post 演示如何在运行时创建EntityConnection。