WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/SQLProvider.Common/SqlRuntime.Common.fs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,8 @@ and ISqlDataContext =
abstract CallSprocAsync : RunTimeSprocDefinition * QueryParameter[] * obj[] -> System.Threading.Tasks.Task<SqlEntity>
/// Get individual row. Takes tablename and id.
abstract GetIndividual : string * obj -> SqlEntity
/// Get individual row asynchronously. Takes tablename and id.
abstract GetIndividualAsync : string * obj -> System.Threading.Tasks.Task<SqlEntity>
/// Save entity to database.
abstract SubmitChangedEntity : SqlEntity -> unit
/// Save database-changes in a transaction to database.
Expand Down Expand Up @@ -1229,6 +1231,7 @@ module public OfflineTools =
| false, _ ->
failwith ("Add table to dummydata: " + pe)
member this.GetIndividual(arg1: string, arg2: obj): SqlEntity = raise (System.NotImplementedException())
member this.GetIndividualAsync(arg1: string, arg2: obj): System.Threading.Tasks.Task<SqlEntity> = raise (System.NotImplementedException())
member this.GetPendingEntities(): SqlEntity list = (CommonTasks.sortEntities pendingChanges) |> Seq.toList
member this.GetPrimaryKeyDefinition(arg1: string): string = ""
member this.ReadEntities(arg1: string, arg2: FSharp.Data.Sql.Schema.ColumnLookup, arg3: Data.IDataReader): SqlEntity array = raise (System.NotImplementedException())
Expand Down
20 changes: 19 additions & 1 deletion src/SQLProvider.DesignTime/SqlDesignTime.fs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,25 @@ module DesignTimeUtils =
, getterCode = getterCode
)
)
|> Array.append( propertyMap |> Map.toArray |> Array.map (snd >> snd))

// Add async method to fetch individual by primary key
let tableName = table.FullName
let pkColumn = columns.[pkName]
let pkType = Utilities.getType pkColumn.TypeMapping.ClrType
let returnType = typedefof<System.Threading.Tasks.Task<_>>.MakeGenericType(tableTypeDef)
let getAsyncMethod =
ProvidedMethod("GetAsync", [ProvidedParameter("id", pkType)], returnType, invokeCode = fun args ->
let a0 = args.[0]
let pkValue = args.[1]
<@@ ((%%a0 : obj) :?> ISqlDataContext).GetIndividualAsync(tableName, %%pkValue) @@>
)
getAsyncMethod.AddXmlDoc(sprintf "<summary>Asynchronously get an individual %s by primary key value</summary>" table.Name)

seq {
yield getAsyncMethod :> MemberInfo
yield! props |> Seq.cast<MemberInfo>
yield! propertyMap |> Map.toSeq |> Seq.map (snd >> snd) |> Seq.cast<MemberInfo>
} |> Seq.toList

propertyMap
|> Map.toSeq
Expand Down
31 changes: 31 additions & 0 deletions src/SQLProvider.Runtime/SqlRuntime.DataContext.fs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,37 @@ type public SqlDataContext (typeName, connectionString:string, providerType:Data
if provider.CloseConnectionAfterQuery then con.Close()
entity

member this.GetIndividualAsync(table,id) =
task {
use con = provider.CreateConnection(connectionString) :?> System.Data.Common.DbConnection
let table = Table.FromFullName table
// this line is to ensure the columns for the table have been retrieved and therefore
// its primary key exists in the lookup
let columns = provider.GetColumns(con, table)
let pk =
match provider.GetPrimaryKey table with
| Some v -> columns.[v]
| None ->
// this fail case should not really be possible unless the runtime database is different to the design-time one
failwithf "Primary key could not be found on object %s. Individuals only supported on objects with a single primary key." table.FullName
use com = provider.CreateCommand(con,provider.GetIndividualQueryText(table,pk.Name)) :?> System.Data.Common.DbCommand
if commandTimeout.IsSome then
com.CommandTimeout <- commandTimeout.Value
//todo: establish pk SQL data type
com.Parameters.Add (provider.CreateCommandParameter(QueryParameter.Create("@id", 0, pk.TypeMapping),id)) |> ignore
if con.State <> ConnectionState.Open then
do! con.OpenAsync()
if con.State <> ConnectionState.Open then // Just ensure, as not all the providers seems to work so great with OpenAsync.
if con.State <> ConnectionState.Closed && provider.CloseConnectionAfterQuery then con.Close()
con.Open()
use! reader = com.ExecuteReaderAsync()
let! entities = (this :> ISqlDataContext).ReadEntitiesAsync(table.FullName, columns, reader)
let entity = entities |> Seq.exactlyOne
reader.Close()
if provider.CloseConnectionAfterQuery then con.Close()
return entity
}

member this.ReadEntities(name: string, columns: ColumnLookup, reader: IDataReader) =
[| while reader.Read() do
let e = SqlEntity(this, name, columns, reader.FieldCount)
Expand Down
Loading