 Sunday, March 01, 2009
Using Miado – Part 4
This is part 4 in a series about the latest release of Miado. In my last post, I discussed about creating an IDbStatement from the IDatabase interface. In this post, I will start to discuss the main methods exposed by the IDbStatement interface. Adding Parameters Adding parameters to the IDbStatement is really easy. It is accomplished simply by calling the AddParameter() method with a name/value pair. The name should match the parameter name declared in the SQL statement and the value is what will be substituted during the query execution. Optionally, you can also set the DBType and/or parameter direction. If the DBType is not set, it will be inferred by the DbProvider implementation based the type of the parameter value. The parameter direction is assumed to be an input parameter unless explicitly declared. This routine should be very familiar to anyone who has ever done traditional ADO.Net development. Like most other methods on the IDbStatement interface, the AddParameter() method returns a reference to itself so it can be chained with other method calls on the IDbStatement interface. Example: 1: private static readonly string INSERT_ADDRESS_SQL =
2: "insert into Address(Address1, Address2, City, State, ZipCode) " +
3: "values(@Addr1, @Addr2, @City, @State, @ZipCode)";
4:
5: public void SaveAddress(Address addr)
6: {
7: this.Database
8: .ExecutingSql(INSERT_ADDRESS_SQL)
9: .AddParameter("Addr1", addr.Address1)
10: .AddParameter("Addr2", addr.Address2)
11: .AddParameter("City", addr.City, DbType.String) // explicitly set DbType
12: .AddParameter("State", addr.State)
13: .AddParameter("ZipCode", addr.ZipCode)
14: .ExecuteNonQuery();
15: }
If you really want total control over the parameter, you can get a reference to the actual DbParameter object using the Action<DbParameter> method signature of AddParameter(). 1: public void UpdateUser(User user)
2: {
3: this.Database
4: .ExecutingSql(UPDATE_USER_SQL)
5: .AddParameter(dbParm =>
6: {
7: dbParm.ParameterName = "Email";
8: dbParm.Value = user.Email;
9: }) // AddParameter(Action<DbParameter> dbParmAction)
10: .AddParameter(dbParm =>
11: {
12: dbParm.ParameterName = "UserID";
13: dbParm.Value = user.UserID;
14: dbParm.DbType = DbType.Int32;
15: dbParm.ParameterDirection.Input;
16: }) // dbParm is a DbParameter
17: .ExecuteNonQuery();
18: }
Insert/Update/Delete
Anytime you want to execute a SQL statement that does not return a result set, you can call the ExecuteNonQuery() method (you probably already realized this fact from previous examples). I’ve thought about adding explicit Save(), Update(), and Delete() methods to the API for clarity sake, but since I’m not providing an ORM, these methods would only be information and could not be guaranteed to perform their exact intended action. In other words, they would merely wrap the ExecuteNonQuery() method, so you could call the Save() method to in fact execute a “delete from User where UserID = @ID” SQL statement with no problems. I would be interested to see what other people thought about this change in the comments. Does the readability of Save(), Update(), and Delete() outweigh the need to validate whether the right one is called? Should there be validation against the raw SQL when one of these methods is called (e.g. explicitly checking the SQL string for “INSERT” when Save() is called)? The validation method option is the route I’m leaning.
Creating Custom Business Objects
When you call QueryForResults() or QueryForOne(), you must use a generic type to declare the type of object that will be created from each row in the result set. Your job will be to create an object for each row as the cursor moves forward in each iteration by mapping the values from the columns in the result set row. Most of the time, this will be a custom business object. However, it could be something as simple as an int if you are just returning a count(*). Both these method types take a delegate that passes in an IResultSetRow interface (which merely wraps a DbDataReader) and return an instance of the generic type you declared. The IResultSetRow interface has both typed - using generics GetValue<T>() - and non-typed - GetValue() - methods that can be used to retrieve values using ordinals or by column name.
If your return type is simple or will not likely be re-used, you can use a lambda expression to create the returned object. 1: private static readonly SELECT_USER_COUNT_SQL = "select count(*) from Users";
2:
3: public int FindUserCount()
4: {
5: return
6: this.Database
7: .ExecutingSql(SELECT_USER_COUNT_SQL)
8: .QueryForOne<int>(row => row.GetValue<int>(0));
9: }
Alternatively, you can create a true delegate method that satisfies the signature required by the QueryForOne() and QueryForResults() methods and pass a reference to the delegate. 1: public IEnumerable<BlogEntry> FindBlogEntriesByBlog(int blogID)
2: {
3: return
4: this.Database
5: .ExecutingSql(SELECT_BLOG_ENTRIES_BY_BLOG_ID_SQL)
6: .AddParameter("BlogID", blogID)
7: .QueryForResults<BlogEntry>(CreateBlogEntry);
8: }
9:
10: private BlogEntry CreateBlogEntry(IResultSetRow row)
11: {
12: return new BlogEntry
13: {
14: BlogEntryID = row.GetValue<int>("BlogEntryID"),
15: Text = row.GetValue<string>("BlogText")
16: // rest of mapping ommitted
17: };
18: }
In my next post, I will describe how to use the IDbStatement to return our old friend DataSet.
Sunday, March 01, 2009 5:29:02 PM (Eastern Standard Time, UTC-05:00) Miado
 Tuesday, February 17, 2009
Using Miado – Part 3
This is part 3 in a series about the new release of Miado. If you want, you can go back and see Part 1 and Part 2 where I talk about creating an IDatabase reference. In this part, I will discuss how to use the IDatabase to create an IDbStatement.
IDbStatement
The IDbStatement interface is the main working component of the Miado API. You need to use this interface to run raw SQL or to execute a stored procedure. Once you get a handle on the interface (from the IDatabase interface), you can begin “building” the statement that will be run against the DB. Most of the methods on the interface return a reference to itself, so the method calls can be chained to form a fluent-type interface.
Executing SQL
Most of the time, I use raw SQL to execute my DB statements. The ExecutingSql() method on the IDatabase interface returns an IDbStatement reference. 1: public class ProductRepository : IProductRepository
2: {
3: private static readonly string SELECT_PRODUCT_BY_ID =
4: "select ProductID, Name, ProductNumber, Color, ListPrice, ProductModel " +
5: "from Products " +
6: "where ProductID = @ID";
7:
8: // more SQL
9:
10: public ProductRepository(IDatabase db)
11: {
12: this.Database = db;
13: }
14:
15: public IDatabase Database
16: {
17: get;
18: private set;
19: }
20:
21: public Product Load(int productID)
22: {
23: IDbStatement dbStmt = this.Database.ExecutingSql(SELECT_PRODUCT_BY_ID);
24: dbStmt.AddParameter("ID", productID);
25: return dbStmt.QueryForOne<Product>(CreateProduct);
26: }
27:
28: // more CRUD methods
29:
30: private Product CreateProduct(IResultSetRow row)
31: {
32: // implementation omitted...
33: }
34: }
As I said before, since the methods on the IDbStatement return themselves, you can chain the calls. In line 21-26, you could change the Load() method to read like this: 1: public Product Load(int productID)
2: {
3: return
4: this.Database
5: .ExecutingSql(SELECT_PRODUCT_BY_ID)
6: .AddParameter("ID", productID)
7: .QueryForOne<Product>(CreateProduct);
8: }
Stored Procedures
Stored Procedures are built up in a similar fashion, except you need to call the CallingStoredProcedureNamed() method to load the SP. 1: public class EmployeeRepository : IEmployeeRepository
2: {
3: public EmployeeRepository(IDatabase db)
4: {
5: this.Database = db;
6: }
7:
8: public IDatabase Database
9: {
10: get;
11: private set;
12: }
13:
14: public IEnumerable<Employee> FindEmployeesByManager(int mgrID)
15: {
16: return
17: this.Database
18: .CallingStoredProcedureNamed("uspGetManagerEmployees")
19: .AddParameter("ManagerID", mgrID)
20: .QueryForResults<Employee>(CreateEmployee);
21: }
22:
23: private Employee CreateEmployee(IResultSetRow row)
24: {
25: // implementation omitted
26: }
27: }
Registered Queries
I showed in my last post how you can use the IDatabase interface to “register” queries. You can easily retrieve them in the IDbStatement interface by using LoadQueryRegisteredAs() method, which will load the corresponding SQL. 1: public IEnumerable<State> FindAllStates()
2: {
3: return
4: this.Database
5: .LoadQueryRegisteredAs("SelectStates")
6: .QueryForResults<State>(
7: row => new State
8: {
9: Abbreviation = row.GetValue<string>("StateCode"),
10: Name = row.GetValue<string>("Name")
11: });
12: }
Running Custom Queries
There is one more way to “load” a query in the IDbStatement interface, and that is by calling the RunningQuery() method, and passing in an object that implements the ISqlQuery interface. That is new functionality to this release and probably deserves its own blog post, so I will cover that later.
In my next post, I will discuss how the IDbStatement executes and discuss the different kinds of return types available, and how you can create custom business objects from the query result set.
Tuesday, February 17, 2009 4:40:52 PM (Eastern Standard Time, UTC-05:00) Miado
 Monday, February 16, 2009
Using Miado - Part 2
This is part 2 in a series on the new updates to the Miado API. You can read the first part in the series here. In this post, I am going to discuss some of the new features available when configuring Miado. Query Registration I’ve had a couple of clients who’ve had a requirement where they wanted to store their SQL in a single location rather than spread across the Repository objects as embedded SQL. In fact, one client put all their SQL in .sql files and stored them on the file system. I had never seen this before, but after working with it for a while I definitely warmed up on the idea. I definitely saw some advantages for doing this: - Versioning – it’s very easy to isolate changes to individual SQL statements, and you can take advantage of all the benefits of using a version control system, like labeling, diffs, branching, etc.
- Testing - you can open the SQL files directly in your DB management software to test the queries (as opposed to cutting and pasting out your source code, where you have to remove code formatting like string concatenations)
- Collaboration – you can easily share the queries with a DBA, who can help tweak them or run profiling tools against them
- Isolation – all your queries are stored in a common well-known place
So I added the capability in Miado to “register” queries by name. You can either do this manually or by pointing to files or a directory on the file system. The IQueryRegistry interface controls the registration and retrieval of stored queries. To get an access to this interface, you need to declare an Action<IQueryRegistry> delegate to configure itself. The delegate is passed in via a method on the IDatabase interface. Registering Queries Manually The easiest way to register queries is by setting name/value pairs: 1: var db = new SqlServerDatabase(connString);
2: db.ConfigureQueryRegistry(queryRegistry =>
3: {
4: string name = "SelectStates";
5: string sql = "select StateCode, Name from States";
6: queryRegistry.RegisterQuery(name, sql);
7:
8: string name1 = "SelectUserByID";
9: string sql1 = "select UserID, Email " +
10: "from Users " +
11: "where UserID = @ID";
12: // NamedQuery is a simple name/value pair object
13: var namedQuery = new NamedQuery(name1, sql1);
14: queryRegistry.RegisterQuery(namedQuery);
15: });
Registering Queries From Files
Alternately, you can register queries from files on the file system. There are multiple ways to do this. First of all, you can start at a selected directory and optionally pass a Predicate to select only certain files. From the resulting files, you need to build a NamedQuery list from each individual file. 1: var db = new SqlServerDatabase(connString);
2: db.ConfigureQueryRegistry(queryRegistry =>
3: {
4: // start looking in the "sql" directory for files named *.sql
5: queryRegistry.RegisterQueriesFromPath(
6: "sql",
7: fileInfo => String.Compare(fileInfo.Extension, ".sql") == 0,
8: fileInfo =>
9: {
10: string queryName = fileInfo.Name.Substring(0, fileInfo.Name.IndexOf('.'));
11: string sql = File.ReadAllText(fileInfo.FullName);
12: return new NamedQuery[] { new NamedQuery(queryName, sql) };
13: });
14: });
You can also pass in the specific files you want processed: 1: var db = new SqlServerDatabase(connString);
2: db.ConfigureQueryRegistry(queryRegistry =>
3: {
4: // find the files yourself
5: string[] files = Directory.GetFiles("sql", "*.sql", SearchOption.AllDirectories);
6: queryRegistry.RegisterQueriesFromFiles(
7: files,
8: fileInfo =>
9: {
10: string queryName = fileInfo.Name.Substring(0, fileInfo.Name.IndexOf('.'));
11: string sql = File.ReadAllText(fileInfo.FullName);
12: return new NamedQuery[] { new NamedQuery(queryName, sql) };
13: });
14: });
Be Smart
Obviously, you need to be careful about exposing the raw SQL in any directory that can be compromised. If you are using a web app, make sure it is not in a publicly visible folder. If you are using a rich client app, you might want to think about using Isolated Storage as your underlying query repository.
In my next post, I will show how to use the IDbStatement to run queries, including those registered in the IQueryRegistry.
Monday, February 16, 2009 1:00:13 PM (Eastern Standard Time, UTC-05:00) Miado
 Sunday, February 15, 2009
Using Miado – Part 1
I released a new version of Miado on CodePlex last night, so I thought I’d spend a couple of blog posts explaining how to use the API. Consider this post as the first in a multi-part series on how to use the newest version. Basics – Creating an IDatabase The first thing you need to do is get a handle on an IDatabase. The interface (and its corresponding implementation) serves as the entry point of the API. Obviously, the easiest way to do so would be to directly new one up. The Database constructor takes in a DbProviderFactory object and a connection string. 1: string connString =
2: "Data Source=localhost;Initial Catalog=MyDatabase; User ID=MyUser; Password=Password1";
3: IDatabase db = new Database(SqlClientFactory.Instance, connString);
I’ve created a few sub-classes of the Database class that take care of the provider initialization (using the corresponding DbProviderFactory implementations provided in the .Net Framework) and just take in a connection string:
- OdbcDatabase
- OleDatabase
- OracleDatabase
- SqlServerDatabase
e.g. 1: string connString =
2: "Data Source=localhost;Initial Catalog=MyDatabase; User ID=MyUser; Password=Password1";
3: IDatabase db = new SqlServerDatabase(connString);
Using Miado with a Depedency Injection Container
I’m a big fan of Dependency Injection, so I normally create a reference to the IDatabase in my application start event and store it in the DI container.
1: public class Global : System.Web.HttpApplication, IContainerAccessor
2: {
3: public IUnityContainer Container
4: {
5: get;
6: protected set;
7: }
8:
9: protected void Application_Start()
10: {
11: this.InitializeContainer();
12: }
13:
14: protected void InitializeContainer()
15: {
16: var container = new UnityContainer();
17:
18: string connString = ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;
19: // create IDatabase instance and store it in the container
20: var db = new SqlServerDatabase(connString);
21:
22: container.RegisterInstance<IDatabase>(db);
23:
24: // create a Repository object - IDatabase will injected in it
25: container.RegisterType<IUserRepository, UserRepository>();
26:
27: // rest of the container initialization omitted ...
28:
29: Container = container;
30: }
31: }
When I create my repository objects, I design them to take a reference to the IDatabase in the constructor. 1: public class UserRepository : IUserRepository
2: {
3: public UserRepository(IDatabase db)
4: {
5: this.Database = db;
6: }
7:
8: public IDatabase Database
9: {
10: get;
11: private set;
12: }
13:
14: // CRUD methods omitted
15:
16: }
17:
The nice thing about the DI container is that it will automatically inject a reference to the IDatabase instance I registered when it resolves the Repository reference. 1: IContainerAccessor accessor = HttpContext.Current.ApplicationInstance as IContainerAccessor;
2:
3: // IDatabase is resolved and injected in UserRepository constructor
4: IUserRepository userRepository = accessor.Container.Resolve<IUserRepository>();
If you don’t want to use a DI container, you can accomplish a similar de-coupling by hiding the IDatabase creation behind a Factory object. 1: public static class DatabaseFactory
2: {
3: private static readonly IDatabase _db =
4: new SqlServerDatabase(ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString);
5:
6: public static IDatabase CreateDatabase()
7: {
8: return _db;
9: }
10: }
In my next post, I will discuss how to use the IDatabase interface to register queries (a new feature in Miado).
Sunday, February 15, 2009 11:23:59 AM (Eastern Standard Time, UTC-05:00) Miado
 Sunday, February 01, 2009
More Love For Lambda Expressions
When I first jumped into C# programming, one of the biggest points of confusion for me was in understanding delegates. You see, Java had no real similar concept. So the idea of function pointers didn’t really register with me. I saw some really weird syntax for event handlers that looked like this: 1: myButton.Clicked += MyButton_Clicked; 2: 3: // ... 4: 5: private MyButton_Clicked(object sender, EventArgs e) 6: { 7: // do something 8: }
Eventually, I caught on that because the function called MyButton_Clicked satisfied the signature required by the OnClick event, it could be added as an event handler to the event.
Aha! Delegates are nothing more than “interfaces” at the method (as opposed to class) level. So even though I understood what delegates were, I still didn’t see a widespread use for them outside event handlers. Sure, I saw examples where they were used, but they all seemed very contrived to me.
Enter in lambda expressions
Lambda expressions were introduced in C# 3.0. I’ve said it before, while lambda expressions are new to .Net, they are not even close to being a new concept in programming languages. They have been around forever. Basically, it’s a terse syntax for defining anonymous delegates. In .Net, they were really a simpler way to interact with LINQ. Now you no longer had to go through the ceremony of creating an explicit method just to satisfy the compiler. This “inline” function call was especially useful in simple delegate calls, as in a Predicate:
1: var myList = new List<Person>(); 2: // ... 3: Person chris = myList.Find(person => person.FirstName == "Chris");
I don’t know why, but I really latched on to lambda expressions in a way I never did with delegates. Which is actually a little weird, since I’ve heard numerous complaints that the lambda expression syntax is too confusing for the average developer.
Changing the way I code
Now, lambda expressions have really changed the way I approach programming. I’ll give an example from Miado. I wanted to add support to Miado for creating typed DataSet objects (in addition to regular DataSet objects). I added support for a querying for a DataSet using generics, where the generic type had to be a class derived from DataSet:
1: public virtual T QueryForDataSet<T>() where T : DataSet
I wanted to have one common method that handles creating both types of DataSets (the ol’ DRY – i.e. “Don’t Repeat Yourself”). Here’s the rub - when using a DataAdapter to fill the DataSet, the method actually is just a little different from using a regular DataSet versus a typed one. It’s not that different, but enough to make you have to handle it two different ways. Previously, I probably would’ve created a template method or maybe handled it through an interface. But to use interfaces would require an interface to define the method and two separate classes to implement the varying implementations. That’s a lot of work to accomplish this seemingly simple task.
Hmm … if I could just pass in the method that I want to call, I can solve this problem much easier. Enter in my good friend Action<T> to the rescue!
Action<T>
Action<T> is a delegate method. It takes in an instance of the generic T type defined in its signature and has no return value. So it’s a callback method that performs some action (and thus cleverly named). I love this delegate. It’s really great for implementing simple one line functions via a lambda expression. The syntax becomes very terse without having to build up all the ceremony just to satisfy the compiler.
Implementation
Actually, Action is overloaded so you can pass in multiple arguments. In my case, I am using two arguments to the method (i.e. Action<T,U>). Here is the way I implemented it:
1: private T QueryForDataSetUsingCustomDataAdapterFillFunction<T>( 2: Action<DbDataAdapter, T> adapterFillFunction) where T : DataSet 3: { 4: T ds = CreateEmptyDataSet<T>(); 5: 6: using ( DbConnection conn = this.Database.CreateConnection() ) 7: { 8: conn.Open(); 9: 10: using ( DbCommand cmd = conn.CreateCommand() ) 11: { 12: cmd.CommandText = this.CommandText; 13: cmd.CommandType = this.CommandType; 14: 15: if ( this.Parameters != null ) 16: { 17: cmd.Parameters.AddEnumeration(this.Parameters); 18: } 19: 20: using ( DbDataAdapter adapter = this.Database.CreateDataAdapter() ) 21: { 22: adapter.SelectCommand = cmd; 23: adapterFillFunction(adapter, ds); 24: } 25: } 26: } 27: 28: return ds; 29: } 30: 31: public virtual DataSet QueryForDataSet() 32: { 33: return QueryForDataSetUsingCustomDataAdapterFillFunction<DataSet>( 34: (adapter, ds) => adapter.Fill(ds)); 35: } 36: 37: public virtual T QueryForDataSet<T>() where T : DataSet 38: { 39: return QueryForDataSetUsingCustomDataAdapterFillFunction<T>( 40: (adapter, ds) => adapter.Fill(ds, ds.Tables[0].TableName)); 41: }
Basically, I made it so that the common method takes in a function that, given a DataAdapter and a DataSet, does some work on those objects. So the two public methods pass in a different implementation of the Fill() method on the DataAdapter. Like I said before, it’s kind of like using interfaces for methods. The common method (in line 23) calls the Action method to perform its specific function by passing back the current DataAdapter and DataSet.
Conclusion
Again, lambda expressions have changed the way I approach programming. Once you get a handle on the syntax, it’s a great tool to have in your toolbox!
Sunday, February 01, 2009 3:46:49 PM (Eastern Standard Time, UTC-05:00) .Net | C# | Miado
 Wednesday, January 28, 2009
Atlanta Alt.Net User Group Meeting
Tonight we are going to have another meeting of the Atlanta alt.net user group. We are meeting at Manuel’s Tavern again, but we are supposed to be in a different room this time. I know the last meeting at Manuel’s was a little hard to find (if you weren’t there, last time they put us in a side room off another room that was holding a meeting, which had closed its outer doors to the rest of the restaurant). This week were are going to be in the “Eagle’s Nest” room, which is located on the other side of the restaurant off the main dining area on its southern side. Look for the small stairs in the corner of the room. We are going to be discussing the book, “Agile Estimating and Planning” by Mike Cohn. If you haven’t read the book, it’s no big deal. We will be discussing lots of other things, too. Hope to see you there!
Wednesday, January 28, 2009 10:01:32 AM (Eastern Standard Time, UTC-05:00) .Net | alt.net | User Groups
|