Сущность SQL без метаданных? - PullRequest
2 голосов
/ 29 сентября 2010

Мне нужно сгенерировать запросы SQL для различных поставщиков баз данных, для схем баз данных, которые не известны во время компиляции. Я вижу, что Entity Framework уже проделал тяжелую работу по предоставлению диалекта SQL под названием Entity SQL, который переводится на собственный SQL перед выполнением, и я надеялся каким-то образом воспользоваться этим.

В идеале я хотел бы просто сгенерировать ESQL, запустить его и получить IDataReader, в то время как Entity Framework беспокоится о деталях поставщика. Однако, похоже, нет способа создать EntityConnection без предоставления метаданных в виде файлов SSDL, CSDL и MSL, и я не буду узнавать о схеме базы данных до времени выполнения.

У меня вопрос: есть ли способ воспользоваться ESQL без какой-либо информации о схеме базы данных во время компиляции? Если необходимо (и возможно), я буду открыт для программного генерирования метаданных из базы данных и их кэширования. Я также был бы открыт для любых инструментов .NET, которые могли бы лучше соответствовать моим потребностям, чем Entity Framework.

Спасибо за ваше время.

Обновление

Благодаря предложению Алекса я смог разобраться, как генерировать метаданные, необходимые для EntityConnection на лету, без записи каких-либо файлов. В результате я смог сделать именно то, на что надеялся. Теперь все, что мне нужно сделать, это выяснить, как извлечь информацию о доступных таблицах / представлениях для собственного использования из сгенерированных метаданных.

Вот мой тестовый код:

#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 Ответ

1 голос
/ 29 сентября 2010

Существует способ создания EntityConnection, указывая соответствующие метаданные (CSDL, MSL и SSDL) во время выполнения.

Фактически это одно из ключевых преимуществ перехода от уровня объектов (классы CLR) к клиенту сущности (eSQL, DataReaders и т. Д.).

Чтобы помочь вам начать это В этом посте показано, как создать EntityConnection во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...