Wednesday, April 15, 2009

New Wine in Old Wine Skins: My First .NET Project

By, "New Wine in Old Wine Skins" I’m not making a techie joke about the “Windows Emulator”. I’m thinking about new projects being created using old technology.

It seems to me there is sometimes an advantage to being new to something. You are not “set in your ways” and have not yet developed bad habits.

Of course, I am new to .NET, but certainly not new to development in general. I may have developed habits developing Java or C++ or working with Unix that may cause me problems with making the transition to .NET. On the other hand, since .NET is all new to me, using its newer features such as WPF, Linq and Ajax should not be anymore difficult to me than learning the old way of doing things which is also new as far as I am concerned.

However, I am helping a friend with a .NET project, and I have found that he was less than open to some of these newer technologies. For example, I saw that his database code relied on hard-coded bits of SQL. Having worked with Hibernate in the Java world, I suggested that he use ORM (object relational mapping).

After a little research on my own, I found it would be fairly easy to generate C# classes that are mapped directly to tables. I started out with the Access database my friend had provided me. To get this process to work, I first had to import the database into Sql Server. This turned out to be easy.

Then I generated DLinq mappings using SqlMetal. The result was an xml file and matching cs file. SqlMetal doesn't work with access files, which is why I had to get the tables into Sql Server. I ran the SqlMetal command below from a cmd prompt sitting in my App_Code folder:


"c:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SqlMetal.exe" /map:Mappings.xml /code:Mappings.cs "C:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA\XXX_Data.mdf"


… where XXX was the name of the database.

For some reason, after importing I had to take down Sql Server and bring it back up before it would work. I am not sure if I was doing something wrong. Of course, the express version of Sql Server doesn't give you much of a UI to work with.

Also, trying to build the project after adding these files I get the following error...


Error 1 The type or namespace name 'Linq' does not exist in the namespace 'System.Data' (are you missing an assembly reference?) C:\Documents and Settings\greg\My Documents\Visual Studio 2008\WebSites\FindEngine\App_Code\Mappings.cs 16 19 C:\...\FindEngine\


I found out I could fix this as follows by adding the following to web.config after the the line for System.Data.DataSetExtensions...

<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=xxxxx">


where the public key token is the same as that used to sign System.Data.DataSetExtensions

I did not actually try using the mappings yet, but wanted to share my work with my friend. When I sent it to him he replied: “I admire your learning DLinq, and applying it here, but I'm pretty sure it won't work, since I'm storing column names as strings and using them to generate parameters for the queries. It's kind of moving the opposite way from LINQ, since you can't do strongly typed in-line queries that way.”

He then supplied some examples from his code. Here it is with some of the names changed…

Here is an example from WidgetObject.cs that I believe is incompatible with the LINQ concept:

    public void Delete(int ID)
    {
        Db.Execute("DELETE FROM " + _type + " WHERE ID = @ID", ID);
    }
Here's another example from WidgetStuff.cs:

    public override DataTable GetList(int ParentID)
    {
        string whereClause = "";
        List<param> paramList = new List<param>();
        if (ParentID > 0)
        {
            whereClause = " WHERE CategoryID = @ParentID";
            paramList.Add(Param.Int("ParentID", ParentID));
        }
        return Db.GetDataTable(string.Concat(
            "SELECT ID, '' AS ChildType, Name AS Name, Description",
            " FROM Stuff", whereClause, " ORDER BY Name"), paramList);
    }

(code formatted by http://formatmysourcecode.blogspot.com/)

My friend must be smarter than me, because I don’t pretend to understand exactly what he is doing. However, I get the impression that maybe he is getting carried away with trying to come up with a very general solution where something simpler would suffice. I think I will be puzzling over this for some time. If I figure it out, I will write another blog about it.

No comments:

Post a Comment