Sponsors

Thứ Ba, 22 tháng 1, 2013

DateTime Start and End of Day Extension Methods

Another quick post with some useful extension methods for the System.DateTime struct. I've been working a lot with the DateTime type over the past couple of weeks. One particular use case has been to pass a "start" and an "end" DateTime to some SQL Server stored procedure. The stored procedure then returns some data based on some timestamp field that falls between the start and end DateTime's passed in.

In the code I was maintaining, the previous developer had created a DateTime value using DateTime.Now, which returns a DateTime with the time part also populated to the current system time. So when passing this DateTime to the stored proc as a "start" DateTime, the proc was looking from the time-part onwards on the specific day represented by the DateTime. Likewise, when using a similarly created DateTime for the "end" DateTime, the stored proc only returned rows upto the time-part. This was undesired behaviour because the original intention was to retrieve all of the records between two specified days (inclusive of the start and end days).

I decided to tackle this at the application-level. This was mainly to keep the stored procedure flexible so that it can continue to handle retrieval of records at the more granular time level if required. I decided to implement this functionality by adding two extension methods on DateTime, namely, ResetTimeToStartOfDay and ResetTimeToEndOfDay. These return new DateTime values with the time part appropriately set. The idea is to call ResetTimeToStartOfDay on the "start" DateTime and ensure that the returned DateTime is sent to the stored procedure. Likewise, call ResetTimeToEndOfDay on the "end" DateTime. I've included the implementation of the two methods below - very simple but useful to have in your library.


public static DateTime ResetTimeToStartOfDay(this DateTime dateTime)
{
   return new DateTime(
      dateTime.Year,
      dateTime.Month,
      dateTime.Day,
      0, 0, 0, 0);
}

public static DateTime ResetTimeToEndOfDay(this DateTime dateTime)
{
   return new DateTime(
      dateTime.Year,
      dateTime.Month,
      dateTime.Day,
      23, 59, 59, 999);
}

Thứ Năm, 17 tháng 1, 2013

Highcharts JS Library - Overwriting Plots Problem

I'm currently working on a small ASP.NET MVC4 application that reports some live numerical data in a chart. My manager pointed me to Highcharts JS which is a neat and simple to setup library. The particular chart type we chose to use was this.

The chart sits in its own partial view. It is periodically polling an action that returns data in JSON format for it to plot along an X-axis representing time. If you take a look at the JavaScript for the demo of the chart we decided to use (link above), it has two places where points are plotted.

Firstly, it plots points when you define a series for the chart - this is where I am plotting all the initial data accumulated since the view was requested by a user. Then, I'm plotting any subsequent data that has just been accumulated using a timer that is defined in the load event for the chart (this is the part that polls the action I mentioned earlier).

When plotting the chart in this way, I ran into an issue when we had no initial data to plot. In this scenario, the chart initially (and correctly) displays as empty. However, as data was coming in from my timer calls to the action - only one point would ever be plotted. After investigating this, it turned out that it was because I was passing in the boolean value true for the "shift" parameter to the Series.addPoint function.

This parameter tells the chart library to shift the graph to the left (thus removing the left-most plot) and hence my last plotted point was always being lost on each poll to the action. This in-turn gave the illusion that my points were being overwritten. To fix this, I passed in a boolean expression that tests if the series has 30 points plotted - this ensured that the chart always displays 30 plotted points at the most and resolved the problem of "overwriting" plotted points!

Thứ Ba, 18 tháng 12, 2012

MongoDB Developer Course Success

A bit off topic today, just some good news. In an earlier post, I mentioned that I was on a MongoDB developer course (ran by 10gen, the MongoDB company). Last week was the final week of the course with the final exam deadline this Monday. The results have just been published - I received a grade of 85% so have officially passed the course (certificates are awarded from 65% onwards).

The course has given me an excellent grounding in MongoDB and I just wanted to thank 10gen for administrating it. It looks like they are running a Java version of the course next year, so I highly recommend any developers interested in MongoDB to enrol onto it.

It's a nice way to end a busy year. Merry Christmas and Happy New Year.

Thứ Tư, 5 tháng 12, 2012

Run Sql Script file in Asp.net C#

EXECUTE SQL Script file in Asp.net C#


To create SQL Database using Asp.net is quite difficult, Here In this article am writing how to create SQL Database and how to Run the SQL Script File in asp.net. These two dlls you have to import to perform these task


  • Microsoft.SqlServer.ConnectionInfo.dll
  • Microsoft.SqlServer.Smo.dll
So that it iterates SQL scripts in a directory and executes them with ConnectionContext.ExecuteNonQuery. 

Code : 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data;
using System.Web.Configuration;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using System.IO;
using System.Xml.Linq;

protected void Page_Load(object sender, EventArgs e)
{
SqlConnection con1 = new SqlConnection("YOUR CONNECTIONSTRING");
}

protected void btn_Click(object sender, EventArgs e)
{
string strdbname=txtdbname.text;
string strCreatecmd = "create database " + strdbname + "";
SqlCommand cmd = new SqlCommand(strCreatecmd, con1);
con1.Open();
cmd.ExecuteNonQuery();
con1.Close();
// Code to execute sql script ie(create tables/storedprocedure/views on ms sqlserver)

//generatescript.sql is sql script generated and placed under Add_data folder in my application
FileInfo file = new FileInfo(Server.MapPath("App_Data\\generatescript.sql"));
string strscript = file.OpenText().ReadToEnd();
string strupdatescript = strscript.Replace("[databaseOldnameWhileSriptgenerate]", strdbname);
Server server = new Server(new ServerConnection(con1));
server.ConnectionContext.ExecuteNonQuery(strupdatescript);
con1.Close();
}

Note: 
  • Microsoft.SqlServer.Smo.dll,Microsoft.SqlServer.ConnectionInfo.dll is need
  • You will find these online or check in ur windows ie In c/programfiles/sqlserver/assembly/...
  • Your databasescript contain "GO" if not using smo.dll it will throw error.

Thứ Ba, 4 tháng 12, 2012

Dynamic Typing and Extension Methods

Earlier today I came across an interesting runtime exception of type RuntimeBinderException. The specific exception message was:

'System.DateTime' does not contain a definition for 'ToUKFormat'

'ToUKFormat' is a custom extension method on DateTime that I wrote and was in-scope at compile time when I called it. So what caused the runtime exception? It turns out that you cannot call an extension method on an object/value that is dynamically typed. In my case, I was using the dynamic ViewBag in an ASP.NET MVC application to store a DateTime value - then in my view, I was retrieving that value from the ViewBag and calling a custom written extension method on it ('ToUKFormat'). In razor syntax, I was doing something similar to:


@ViewBag.Foo.Bar.ToUKFormat()
I have given the solution further below but if you want to reproduce the problem in a simple console application, you can use the following code:


namespace DynamicRuntimeIssue
{
class Program
{
static void Main(string[] args)
{
dynamic today = DateTime.Today;

Console.WriteLine(today.ToUKFormat()); // Exception...
Console.ReadLine();
}
}

static class DateTimeExtensions
{
public static string ToUKFormat(this DateTime dateTime)
{
return dateTime.ToString("dd/MM/yyyy");
}
}
}
When you run the code above, you will encounter the aforementioned exception. Of course, if you appropriately type the 'today' variable to a DateTime rather than dynamic, then you'll find that it all works as expected. However, if you cannot avoid the use of dynamic, like for example in my case where I was using ViewBag - then you can overcome this exception by calling your extension method as if it was any normal static method. You call the method and pass-in your object/value through as an actual parameter. Following on from the example above, you would therefore have:


Console.WriteLine(DateTimeExtensions.ToUKFormat(today));
Rather than:


Console.WriteLine(today.ToUKFormat());
If you want to understand why you can't call extension methods on a dynamic type, then go over to this stackoverflow question where someone else has had the same issue - you will particularly want to read Eric Lippert's response dated March 15 2011.

Thứ Bảy, 24 tháng 11, 2012

CRUD against MongoDB via C#

In my previous post, I gave some of my first thoughts about NoSQL in relation to MongoDB. In this post we will look at how you can perform basic CRUD operations against a MongoDB collection using the official C# driver. The purpose of this post is for me to use it as a handy reference when working with MongoDB in the future - hopefully you'll also find it useful. I will assume that the reader has some familiarity with using MongoDB on the shell.

Throughout the post I'll be using a simple collection of documents where each document stores some basic information about an aircraft. If you load the MongoDB shell and execute the following statements then we'll have a common ground to start with:
use mongotest
db.planes.insert({
'Manufacturer':'Lockheed Skunk Works',
'Model':'Blackbird SR-71',
'FirstFlight': new Date('12/22/1964')
})
db.planes.insert({
'Manufacturer':'Lockheed Skunk Works',
'Model':'X-55 ACCA',
'FirstFlight': new Date('06/02/2009')
})
At this point, you should have a database called mongotest with one collection containing two JSON documents. You can verify this by executing:
db.planes.find().pretty()
We'll now access and modify the planes collection using the C# driver. You can download the driver from here or add it to your solution using the NuGet package (it's easy to do using the NuGet package manager in Visual Studio). For this post, I'm using version 1.6.1 of the official MongoDB C# driver. Assuming you now have added references to MongoDB.Bson.dll and MongoDB.Driver.dll, add the following three using statements at the top of your class (FYI, I practiced with a standard console application directly within the Main method):

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
Now we can define a class that will map to a single plane document. We will use this class along with the MongoDB generic C# driver methods to insert, retrieve, update and remove documents from our planes collection.
public class Plane
{
public ObjectId Id { get; set; }
public string Manufacturer { get; set; }
public string Model { get; set; }
public DateTime FirstFlight { get; set; }
}
Note how we're using the MongoDB.Bson.ObjectId type for our identifier property (we're relying on MongoDB to add unique id's to newly inserted plane documents). Also note that the Plane class must support a parameterless constructor for the driver to be able to work with it.

Let's now take a look at how you can insert a new plane document into the planes collection using the driver. We'll first get a handle on the planes collection, I have the following four lines at the top of my Main method that gives me the required reference (planesCollection):
var connectionString = "mongodb://localhost/?safe=true";
var server = MongoServer.Create(connectionString);
var mongotestdb = server.GetDatabase("mongotest");
var planesCollection = mongotestdb.GetCollection("planes");
To insert a new document into the planes collection (note that the Id property will be filled-in by the insert method):
planesCollection.Insert(new Plane {
Manufacturer = "Unknown",
Model = "Tornado IDS/ECR",
FirstFlight = new DateTime(1974, 8, 14)
});
To retrieve a list of all the documents in the planes collection:
var planes = planesCollection.FindAll().ToList();
To retrieve a list of filtered documents - let's say we want only the planes that are manufactured by Lockheed:
var lockheedPlanes = planesCollection.Find(
Query.EQ("Manufacturer", "Lockheed Skunk Works"))
.ToList();
To update a document (as a whole block) in the planes collection:

var planeToUpdate = planesCollection.FindOne(
Query.EQ("Manufacturer", "Unknown")
);
planeToUpdate.Manufacturer = "Panavia Aircraft GmbH";
planesCollection.Save(planeToUpdate);
Note that you can also perform a partial update to a document (not as a block), refer to the Update method on the MongoCollection class.

Finally, to remove a set of documents based on a query from the planes collection - in this case we'll remove all planes manufactured by Lockheed from the collection:

planesCollection.Remove(
Query.EQ("Manufacturer", "Lockheed Skunk Works")
);

Thứ Sáu, 9 tháng 11, 2012

Initial thoughts on NoSQL with MongoDB

I have heard about the NoSQL movement for a while now but only recently started to properly look into a NoSQL technology. A few weeks ago I found out that 10gen (the team behind the popular NoSQL database called MongoDB) are starting a free "MongoDB for developers" course. The course runs weekly, with each week containing a number of videos that you watch, take a quiz on and then submit homework for. So far it has been very useful despite some initial hiccups in administrating the course. We're now starting Week 3 and have already covered quite a lot about NoSQL in general and how MongoDB can be used in a CRUD sense.
 
Week 3 of the course dives deeper into schema design in MongoDB and compares this with schema design in the more familiar relational data model. The course also has a project that runs throughout - which is to create a simple blogging engine using MongoDB and Python. It seems like the future weekly homeworks are going to be geared towards extending the blogging engines' functionality. Although the course material is using Python to communicate with MongoDB, there are a number of driver libraries that you can download from the MongoDB website for other programming languages - such as C#. I haven't had a chance to play with the C# driver yet but plan on writing a blog post about my experience with it in the future.
 
My training at university and all of the work experience I have gained so far has been around working with relational database management systems. So it is quite exciting moving away from the relational mindset and thinking about a different way to persist application data. It is weirdly refreshing to work with JSON documents in collections than working with the tables and rows abstraction in relational databases.
 
One thing that the course instructors emphasise about MongoDB is that your schema design should be geared towards how your application will access your data. So unlike in a relational data model, where you typically normalise your model to the third normal form - in MongoDB your data model will reflect the access pattern your application will use to get or update the data. As MongoDB doesn't provide support for joining data, you typically model your data (or JSON documents) so that each document contains all of the necessary information your application will regularly need for a particular use case. This is interesting as I think there is an implicit assumption here that you'd only ever have one particular access pattern for your MongoDB database... for example what if I wanted to build another application that accesses the data for a purpose that is different from when the original MongoDB database was designed? I'm hoping the answer to this question is not along the lines of migrating/copying the data to a schema that's more appropriate for the new application!
 
At this stage of my exploration, another concern with MongoDB is that there doesn't seem to be a quick out-of-the-box method to generate a pretty looking report for the data stored in the collections. In the relational world, SQL with the table and rows abstraction lends itself nicely to generating reports that non-technical users can easily make sense of. With MondoDB, you can query your collections of JSON documents easily enough in the shell using mongo.exe and the find() method on a collection - but the resulting output is in JSON format which probably won't go down too well with a non-technical user. Having said this, there may still be solutions/explanations to these concerns that I haven't come across - so I'm definitely not letting them stop me from diving deeper into the NoSQL MongoDB world.