Reputation: 41858
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))"
Upvotes: 3
Views: 220
Reputation: 243051
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).
Upvotes: 5