How to use "use" binding in SqlTransaction - f#

In MSSQL Server I have a database named TestDB that contains a single table with three column (Id, FirstName, LastName) named TestTable. To insert rows into TestTable I have declared a type
type Person = { Id:int; FirstName:string; LastName:string }
two methods 1) Parameters and 2) Transaction
let Parameters(person:Person) =
[|
SqlParameter("#Id", person.Id)
SqlParameter("#FirstName", person.FirstName)
SqlParameter("#LastName", person.LastName)
|]
let Transaction(tsql, sqlcon, sqltran, sqlparam) =
let cmd = new SqlCommand(tsql, sqlcon, sqltran);
for p in sqlparam do
cmd.Parameters.Add(p) |> ignore
cmd
in main method of my Console Application I have used the type and methods in this way
let population = [{Person.Id = 1; Person.FirstName = "Emon1"; Person.LastName = "Haque1"}
{Person.Id = 2; Person.FirstName = "Emon2"; Person.LastName = "Haque2"}]
let query = #"INSERT INTO TestTable VALUES(#Id, #FirstName, #LastName)"
let conStr = #"server=EMON; database=TestDB; user=TestUser; password=TestPass"
use con = new SqlConnection(conStr)
con.Open()
let trans = con.BeginTransaction()
try
population
|> List.iter(fun x -> Transaction(query, con, trans, Parameters(x)).ExecuteNonQuery() |> ignore)
|> trans.Commit
with
| exn -> trans.Rollback()
I have used use once for SqlConnection in main method.
Should I use it for SqlCommand in Transaction function, con.BeginTransaction() and in case of calling Transaction as it returns SqlCommand in main method or use con will take care of all?

If you're familiar with C#, then use works like using in C#. When the values go out of scope, Dispose is called. As a general rule, if you don't use values, then Dispose isn't called.
Some .NET APIs have options for disposing of contained disposable. As an example, StreamReader will automatically dispose of the Stream is contains, unless explicitly constructed with a constructor overload where you can override that behaviour.
As far as I'm aware, though, there's no consistency in such APIs, so you can't rely on hierarchies of disposables to behave that way.
Specifically, I don't see any overloads of BeginTransaction that specify how the returned transaction relates to the connection that created it, and the documentation doesn't say, either. I'd use the trans value, instead of hoping that ill-defined behaviour in the BCL will do the right thing.

Related

let vs member for private functions, in F#

Let's consider this code:
type TransactionTypes =
| TransactionType1
| TransactionType2
type Test() =
let mutable lastTransactionType1 = DateTime.MinValue
let mutable lastTransactionType2 = DateTime.MinValue
let getLastTransaction transaction =
match transaction with
| TransactionType1 -> lastTransactionType1
| TransactionType2 -> lastTransactionType2
let updateLastTransaction transaction =
match transaction with
| TransactionType1 -> lastTransactionType1 <- DateTime.UtcNow
| TransactionType2 -> lastTransactionType2 <- DateTime.UtcNow
Now (with the understanding that I'm still learning F#), I would like to clarify a couple things:
Something like:
let a = DateTime.Now
does a permanent binding, so 'a' will always be the same time on subsequent uses.
But, my understanding is that if there is a parameter, like:
let a anyParameter = DateTime.Now
will be re-evaluated every time due to the presence of the parameter. Is that correct?
In the code above, the two let statements (getLastTransaction and updateLastTransaction) are private to the type (Test)
I could also have implemented them as:
member private this.getLastTransaction = ...
member private this.updateLastTransaction = ...
Is there any reason, for private functions to prefer let vs. member private this?
"let mutable" already implies the this. so the fields are accessible by both forms.
So, what is the advantage of one form vs. the other?
When you are working with members, F# inherits a lot of things from the .NET object model. A .NET object can have a couple of different things:
Fields - those are storing a value (just like fields of a record). They can be mutable or immutable.
Methods - those can be invoked with zero or more arguments (like functions)
Properties - those have no arguments (like fields); they can be read or written, but when this happens, some code is invoked. A property is basically a pair of getter and setter methods.
In F#, some of this is less visible. However, let corresponds to a field and member with arguments corresponds to a method. Your tricky case is a member without arguments. For example:
type A() =
member x.Foo = printfn "Hi"; 42
Will Hi be printed only once, or will it be printed each time you access Foo? To answer, it's useful to know that Foo is a property with a getter. The above is actually a syntactic sugar for the full version:
type A() =
member x.Foo
with get() = printfn "Hi"; 42
Now you can see that there is a method behind the Foo property! Each time you access Foo, the compiler will generate a call to the get() method, so Hi will be printed repeatedly.
In addition to Tomas' answer:
let mutable lastTransactionType1 = DateTime.MinValue
is equivalent in C# to:
internal DateTime lastTransactionType1 = DateTime.MinValue;
and
member private this.getLastTransaction ...
is the same IL as far as IL is concerned with
let getLastTransaction ...
In equivalent C#, both are
internal DateTime getLastTransactionMember(TransactionTypes transaction)
{
if (transaction.Tag != 1)
{
return lastTransactionType1;
}
return lastTransactionType2;
}
But for using F# in an idiomatic way, you would want to go with let.
There's also a difference in that member does let you use the methods in bindings before their declaration, which might be useful in some cases (read: hacks)
let getType1 = this.getLastTransactionMember TransactionType1 //this compiles
member private this.getLastTransactionMember transaction =
match transaction with
| TransactionType1 -> lastTransactionType1
| TransactionType2 -> lastTransactionType2

Dealing with .NET generic dictionaries in F#?

I am not a functional programmer.
I am learning F#.
I got a problem here.
Let me start from following piece of code:
type XmlNode(tagName, innerValue) =
member this.TagName = tagName
member this.InnerValue = innerValue
member this.Atts = Dictionary<string, obj>()
I don't use F# dict because (as I know) that one is readonly, however I obviously need to modify my attributes.
So I am really struggling to make it pure functional way:
type XmlNode with member this.WriteTo (output:StringBuilder) =
output.Append("<" + this.TagName) |> ignore
//let writeAtts =
// List.map2 (fun key value -> " " + key + "=" + value.ToString())
(List.ofSeq this.Atts.Keys) (List.ofSeq this.Atts.Values)
// |> List.reduce (fun acc str -> acc + " " + str)
//output.Append((writeAtts)) |> ignore
output.Append(">" + this.InnerValue + "</" + this.TagName + ">") |> ignore
output
The code I commented out was my (probably stupid) attemp to use mapping and reduction to concat all the atts in the single correctly formatted string. And that compiles OK.
But when I try to access my Atts property:
[<EntryPoint>]
let main argv =
let root = new XmlNode("root", "test")
root.Atts.Add("att", "val") // trying to add a new KVP
let output = new StringBuilder()
printfn "%O" (root.WriteTo(output))
Console.ReadLine()|>ignore
0 // return an integer exit code
...new attribute does not appear inside the Atts property, i.e. it remains empty.
So:
1) help me to make my code more functional.
2) and to understand how to deal with modificable dictionaries in F#.
Thank you.
First, your immediate problem: the way you defined the Atts property, it's not one value that is "stored" somewhere and is accessible via property. Instead, your definition means "every time somebody reads this property, create a new dictionary and return it". This is why your new attribute doesn't appear in the dictionary: it's a different dictionary every time you read root.Atts.
To create a property with a backing field and initial value, use member val:
type XmlNode(...) =
...
member val Atts = Dictionary<string,object>()
Now, answers to some implied questions.
First order of business: "modify the attributes" and "purely functional" are contradictory ideas. Functional programming implies immutable data. Nothing changes ever. The way to advance your computation is to create a new datum at every step, without overwriting the previous one. This basic idea turns out to be immensely valuable in practice: safer threading, trivial "undo" scenarios, trivial parallelization, trivial distribution to other machines, and even reduced memory consumption via persistent data structures.
Immutability is a very important point, and I urge you not to glance over it. Accepting it requires a mental shift. From my own (and other people I know) experience, it is very hard coming from imperative programming, but it is well worth it.
Second: do not use classes and properties. Technically speaking, object-oriented programming (in the sense of message passing) is not contradictory to functional, but the Enterprise flavor that is used in practice and implemented in C++, Java, C# et al., is contradictory, because it emphasizes this idea that "methods are operations that change an object's state", which is not functional (see above). So it's better to avoid object-oriented constructs, at least while you're learning. And especially since F# provides much better ways to encode data:
type XmlNode = { TagName: string; InnerValue: string; Atts: (string*string) list }
(notice how my Atts is not a dictionary; we'll come to this in a bit)
Similarly, to represent operations on your data, use functions, not methods:
let printNode (node: XmlNode) = (* we'll come to the implementation later *)
Third: why do you say that you "obviously" need to modify the attributes? The code you've shown does not call for this. For example, using my definition of XmlNode above, I can rewrite your code this way:
[<EntryPoint>]
let main argv =
let root = { TagName = "root"; InnerValue = "test"; Atts = ["att", "val"] }
printfn "%s" (printNode root)
...
But even if that was a real need, you shouldn't do it "in place". As I've described above while talking about immutability, you should not mutate the existing node, but rather create a new node that differs from the original one in whatever way you wanted to "modify":
let addAttr node name value = { node with Atts = (name, value) :: node.Atts }
In this implementation, I take a node and name/value of an attribute, and produce a new node whose Atts list consists of whatever was in the original node's Atts with the new attribute prepended.
The original Atts list stays intact, unmodified. But this does not mean twice the memory consumption: because we know that the original list never changes, we can reuse it: we create the new list by only allocating memory for the new item and including a reference to the old list as "other items". If the old list was subject to change, we couldn't do that, we would have to create a full copy (see "Defensive Copy"). This strategy is known as "Persistent Data Structure". It is one of the pillars of functional programming.
Finally, for string formatting, I recommend using sprintf instead of StringBuilder. It offers similar performance benefits, but in addition provides type safety. For example, code sprintf "%s" 5 will not compile, complaining that the format expects a string, but the final argument 5 is a number. With this, we can implement the printNode function:
let printNode (node: XmlNode) =
let atts = seq { for n, v in node.Atts -> sprintf " %s=\"%s\"" n v } |> String.concat ""
sprintf "<%s%s>%s</%s>" node.TagName atts node.InnerValue node.TagName
For reference, here's your complete program, rewritten in functional style:
type XmlNode = { TagName: string; InnerValue: string; Atts: (string*string) list }
let printNode (node: XmlNode) =
let atts = seq { for n, v in node.Atts -> sprintf " %s=\"%s\"" n v } |> String.concat ""
sprintf "<%s%s>%s</%s>" node.TagName atts node.InnerValue node.TagName
[<EntryPoint>]
let main argv =
let root = { TagName = "root"; InnerValue = "test"; Atts = ["att", "val"] }
printfn "%s" (printNode root)
Console.ReadLine() |> ignore
0

How do I correctly return a sequence of classes with the query expression?

I am new to F# and having trouble translating some C# code.
I have a class similar to this:
type car () =
member val Model = "" with get,set
member val Year = "" with get,set
I have this query expression that pulls car data from the database:
query{
for row in db do
select // <-- what is the correct syntax to create a sequence of new car
// classes here
}
it's a lot easier if you don't translate 1:1 or at least if you add an constructor.
For example using a primary-constructor this should work:
type Car (model, year) =
member __.Model with get() = model
member __.Year with get() = year
query {
for row in db do
select (Car (row.Model, row.Year))
}
now of course I don't know how the rows in your db looks like and this will give you immutable data - but for what I see it should be fine
I just realised that this might be a problem (just as in C#) as the ctor probably cannot be translated into a SQL-statement - you can still try but I guess you really need to do
query {
for row in db do
select
} |> Seq.map (fun row -> Car (row.Model, row.Year))
instead (sorry - cannot really try right now)

Why I'm getting null for a string in F#?

One of the benefits of the type system on F# is avoid a null exception... or that was something I believe... because I'm getting a null problem:
[<CLIMutable>]
type Customer = {
[<AutoIncrement>] id:option<int64>
code:string
name:string
}
I'm running a SQL code:
let SqlFTS<'T>(table:string, searchTable:string, query:string) =
use db = openDb()
let sql = sprintf "SELECT * FROM %s WHERE id in (SELECT docid FROM %s WHERE data MATCH %A)" table searchTable query
printfn "%A" sql
db.SqlList<'T>(sql) |> Seq.toArray
testCase "Customers" <|
fun _ ->
let rows = GenData.genCustomers(50)
Customers.insert(rows)
isEqual "Failed to insert" 50L (DB.SqlCount<Customers.Customer>())
//Until here, it works
let c = Customers.byId(1L)
printfn "%A" c
//Customers.byId return me a record with all the properties as NULLS!
//Then c.name is null, and the code above fail.
let rows = Customers.searchCustomers(c.name)
This was very unexpected. Why I can get a record with all values to null?
Let's start with line 1:
[<CLIMutable>]
The docs for CLIMutable state
Adding this attribute to a record type causes it to be compiled to a Common Language Infrastructure (CLI) representation with a default constructor with property getters and setters.
That default constructor means the fields will be initialized to default values. The default value for string is null. That's valid to the CLR and it's valid to C# and VB.NET. You may not be able to call the default ctor from F#, but pretty much anyone else can.
Welcome to interop; it can be a pain.

F#: Class with no default constructor as type parameter?

I have a FileReader class whose job is to read and process text files using a StreamReader. To facilitate unit testing, I'd like to provide a type parameter to this class so that I can swap the StreamReader for a FakeReader that doesn't actually interact with the file system (and maybe throws exceptions such as OutOfMemory, so I can test the error handling in FileReader).
Ideally, I'd like to define FileReader something like this (trivialized for clarity):
type FileReader<'Reader> =
member this.Read file =
use sr = new 'Reader(file)
while not sr.EndOfStream do
printfn "%s" <| sr.ReadLine()
and simply define FakeReader to have a constructor that takes the file name, the EndOfStream property getter, the ReadLine() method, and the (empty) Dispose() method. However, F# has several complaints about this type definition, including "Calls to object constructors on type parameters cannot be given arguments." Since StreamReader has no default constructor, this approach seems like a no-go.
So far the only way I've gotten this to work is to inherit FakeReader from StreamReader:
type FakeReader() =
inherit StreamReader("") with
override this.ReadLine() = "go away"
member this.EndOfStream = false
member this.Dispose() = ()
and use a factory method that returns either a new FakeReader or a new StreamReader as appropriate.
type ReaderType = Fake | SR
let readerFactory (file : string, readerType) =
match readerType with
| Fake -> new FakeReader() :> StreamReader
| SR -> new StreamReader(file)
type FileReader(readertype) =
member this.Read file =
use sr = readerFactory(file, readertype)
while not sr.EndOfStream do
printfn "%s" <| sr.ReadLine()
This seems a lot less elegant. Is there a way to do this with a type parameter? Thanks to all.
Using a function that creates a reader object (as suggested by MizardX) is the direct answer to your question. However, I'd maybe consider using a different abstraction than TextReader). As Ankur mentioned in a comment, you could use a more functional approach.
If you're just reading lines of text from the input using TextReader, you could use a seq<string> type instead. The FileReader type may actually be just a function taking seq<string> (although that may be oversimplification... it depends).
This makes it more "functional" - in functional programming, you're often transforming data structures using functions, which is exactly what this example does:
open System.IO
/// Creates a reader that reads data from a file
let readFile (file:string) = seq {
use rdr = new StreamReader(file)
let line = ref ""
while (line := rdr.ReadLine(); !line <> null) do
yield !line }
/// Your function that processes the input (provided as a sequence)
let processInput input =
for s in input do
printfn "%s" s
readFile "input.txt" |> processInput
To test the processInput function, you could then create a new seq<string> value. This is significantly easier than implementing a new TextReader class:
let testInput = seq {
yield "First line"
yield "Second line"
raise <| new System.OutOfMemoryException() }
testInput |> processInput
You could pass in a function that constructs and returns an object of your desired type.
type FileReader(f : string -> TextReader) =
member this.Read file =
use sr = f file
while sr.Peek() <> -1 do
printfn "%s" <| sr.ReadLine()
type FakeReader() =
inherit StringReader("")
override this.ReadLine() = "go away"
override this.Peek() = 0
let reader1 = new FileReader(fun fn -> new StreamReader(fn) :> _)
let reader2 = new FileReader(fun fn -> new FakeReader() :> _)
Cast was necessary because I dropped the generic type-argument, but the actual type can be inferred.

Resources