I can't see what I am doing wrong, as the files are in the correct order. In this case it is:
They are in the same namespace, but even when I had them in different modules, and opened the module in CreateDatabase the same error.
The error is:
Error 1 The value or constructor 'execNonQuery' is not defined
I am trying to inherit BaseDAO and use a member that will be common to several files, and I don't see why I get the error above.
namespace RestaurantServiceDAO
open MySql.Data.MySqlClient
type BaseDAO() =
let connString = @"Server=localhost;Database=mysql;Uid=root;Pwd=$$$$;"
let conn = new MySqlConnection(connString)
member self.execNonQuery(sqlStr) =
conn.Open()
let comm = new MySqlCommand(sqlStr, conn, CommandTimeout = 10)
comm.ExecuteNonQuery |> ignore
comm.Dispose |> ignore
The type that does inherit is here, and execNonQuery is not defined.
namespace RestaurantServiceDAO
open MySql.Data.MySqlClient
type CreateDatabase() =
inherit BaseDAO()
let createRestaurantTable conn =
execNonQuery "CREATE TABLE restaurant(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), cur_timestamp TIMESTAMP(8))"
In F#, inherited members (as well as members defined in the current type) cannot be called implicitly just by the name of the member - you need to refer to the instance of the type somehow. In your case, you can use the base keyword. The following should work:
type CreateDatabase() =
inherit BaseDAO()
let createRestaurantTable conn =
base.execNonQuery "..."
[EDIT] This works only if createRestaurantTable is a member - not a function declared using let (as in the example above). The reason is that F# compiler doesn't allows caputring base in a closure and it interprets the sample above as a closure. You can turn it into member and write:
type CreateDatabase() =
inherit BaseDAO()
private member x.createRestaurantTable conn =
x.execNonQuery "..."
[/EDIT]
Alternatively, you can also name the current instance of the type using as self (which is similar to specifying the instance using member self.Foo() = .. in member declarations. This also allows you to call members of the current type from the constructor:
type CreateDatabase() as self =
inherit BaseDAO()
let createRestaurantTable conn =
self.execNonQuery "..."
I'd prefer the base keyword if that's possible (because refering to the current instance in the constructor causes all sorts of headaches to the compiler).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With