easyBlog

EasyObjects and the Enterprise Library

About the author

Author Name is someone.
E-mail me Send mail

Recent comments

Authors

Tags

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Data Migration and EasyObjects

I just wanted to post this code, because sometimes I find it hard to believe that things can go so smoothly when using EasyObjects and MyGeneration. Quite simply, they rock!

I needed to migrate the Comments from the old DNN blog to the BlogEngine database. Although I could have done it using T-SQL, the code would have been unwieldy and hard to debug. So instead I chose to whip up some code using EasyObjects. It literally took 20 minutes and worked on the first try, no debugging required. I can't promise you exactly the same results with your project, of course, but it is a good example of how quickly you can develop database applications once you become comfortable with the tools you use.

By request, I can make the code available for download, although I doubt it would be of much use to anyone because it is very specific (DNN to BlogEngine). Sorry for the lack of comments in the code, but I don't plan on using the code ever again, so why take the time?

static void Main(string[] args)
{
    Blog_Comments oldComment = new Blog_Comments();
    oldComment.Where.Title.Value = "Cialis";
    oldComment.Where.Title.Operator = WhereParameter.Operand.NotContains;
    oldComment.Query.AddOrderBy(Blog_CommentsSchema.EntryID);
    
    oldComment.Query.Load();

    PostComment newComment = new PostComment();
    do
    {
        Blog_Entries oldEntry = new Blog_Entries();
        oldEntry.LoadByPrimaryKey(oldComment.EntryID);

        Posts newEntry = new Posts();
        newEntry.Where.Title.Value = oldEntry.s_Title;
        newEntry.Query.Load();

        newComment.AddNew();
        newComment.s_Author = oldComment.s_Author;
        newComment.s_Comment = oldComment.s_Comment;
        newComment.s_CommentDate = oldComment.s_AddedDate;
        newComment.s_Country = "us";
        newComment.s_Email = "noreply@noonanconsultinginc.com";
        newComment.s_Ip = "127.0.0.1";
        newComment.IsApproved = true;
        newComment.s_PostID = newEntry.s_PostID;
        newComment.s_Website = "http://www.easyobjects.net";

    } while (oldComment.MoveNext());

    Console.WriteLine(newComment.ToXml());
    newComment.Save();

    Console.WriteLine("\n\nPress <Enter> to continue...");
    Console.ReadLine();
}

 

And here is the complete list of files:

BlogCommentXfer

Remember, that's going from a blank project to a fully-functional table migration in 20 minutes, including dynamic SELECT queries, table-to-table column mapping, null-value handling, looping through results and a batch INSERT at the end (by calling Save()). If I had thought of it, I could have added a transaction wrapper around the whole thing in another minute. In fact, it has almost taken me as long to write this blog post as it did to write the code and migrate the data.

Pretty damn cool.

kick it on DotNetKicks.com


Tags:
Categories: EasyObjects
Posted by mgnoonan on Wednesday, February 20, 2008 12:33 AM
Permalink | Comments (1) | Post RSSRSS comment feed

When your WCF service stops responding

My venture into WCF is proving to be quite educational, in some ways more stressful than others. Today I had a client trying to run a demo, but their service calls were routinely locking up and they kept having to restart the web server. So much for having a day off...  :-(

So I drove to the client, fired up my WCF test harness, ran a couple of tests and everything seemed to be working just fine. So I loaded up the AJAX-driven web site, and sure enough I could make the service lock up after just a few callbacks to the server. Back to my test harness, only this time I decided to add some looping in order to simulate the multiple calls made by the web browser. This time, I was able to lock up the service in my test harness as well.

So what was the solution?

It turns out that when you create the proxy for the service call, it is very important that you also call Dispose(). I guess I got a little lazy and tried to count on the garbage collection to take care of it, but my code was actually starving the service pool of available threads, and so it stops responding until the web server is restarted or the application pool cycles.

So I'm posting this here hoping that others will learn from my mistake: make sure you call Dispose() directly on your service proxy object, or use the "using" statement which will do it for you automatically.

 

HelloServiceClient proxy = new HelloServiceClient();
string result = proxy.HelloWorld(textBox1.Text);
proxy.Close();
proxy.Dispose();
 

-- OR --

 

using (HelloServiceClient proxy = new HelloServiceClient()) 
{ 
    string result = proxy.HelloWorld(textBox1.Text); 
}

 

In my next post, I will review the WCF support now in EasyObjects. Way cool.

kick it on DotNetKicks.com

 


Tags:
Categories: WCF
Posted by mgnoonan on Tuesday, February 19, 2008 12:00 AM
Permalink | Comments (7) | Post RSSRSS comment feed

EasyObjects.NET Roadmap for 2008

As I said in my last post, it's time to stop waiting around and move on to something better. And 2008 should be a great year, so it's time to get going!

First things first, and that's to get going on the beta testing for Access, MySql and Firebird I announced last year. There have been a few volunteers, but not as many as I hoped. I attributed this to the fact that I chose the holiday season to make the announcement, but it's February now. So I am emailing the people who asked to test and sending them a full copy of the current build of EO2 (not the free build) and the associated database modules.

Once that is underway, my next crucial task is to get the EasyObjects Store up and running. I have the basic web site ready, an SSL certificate and PayPal integration set to go. So after some testing, my goal is to have the store online before the end of Q1. The initial version of EO2 available for purchase will be a beta, but any purchases will entitle the user to free upgrades to all beta releases and the full EO2 once it becomes finalized. There will be no support levels available until after release, because that is all still under consideration.

The next big enhancement for EO2 is coming from a project I am working on, and that is WCF. I have modified the templates to generate the Operation and Data Contracts, as well as some lightweight, serialize-friendly classes to help EO work with WCF. It's still in the early stages, but WCF is too cool a technology not to support in EO. Target for a beta release is Q2.

For Q3 and beyond, there will probably be a new release of the Enterprise Library to deal with, we will finalize support for the new database modules, and finally a full release of EO2 in the Store.

That's my current plan, which will promptly go to shit faster than I can blink an eye, but at least it gives us some goals to shoot for.

I welcome your feedback.


Tags:
Posted by mgnoonan on Tuesday, February 12, 2008 11:43 PM
Permalink | Comments (1) | Post RSSRSS comment feed

Switching to BlogEngine.NET

I've been waiting and waiting for the DNN Blog project to get "up to speed" with some new features and functionality, and now that I have a moment to catch my breath, I realize I am done waiting. The DNN Blog is a nice, quick plug-in to the DNN web site that allowed me to setup a blog with relative ease. And time being a precious commodity for me, quick sometimes overrides better.

Well, it's time to move away from something quick and towards something better.

I had hoped that the DNN Blog project would be adding support for things like Live Writer, Pingbacks, social bookmarks and tag clouds. But alas, the project seems as mired in a slowdown as EasyObjects...  :-p

So after a brief search, and trying to decide whether I wanted to host my own (as I do currently) or move to one of the public blog hosting providers, I decided to give BlogEngine.NET a try. In addition to self hosting, I can probably migrate my existing entries without having to re-type everything, which is a plus. And it supports most of the features I was looking for. And more importantly, the project seems to be moving forward with active development. (I know, more on the EO plan in a sec!)

But this change doesn't come without cost, either, and I don't mean just setup and migration time. One key feature of the DNN Blog is the integration with the DNN Search engine. By moving to a separate engine, so too will the search capability for blog posts. No longer will you be able to use the search box on the home page to search the blogs, you will have to go to the blog page and use the search engine there.

Then there are the URL changes, but those will pass over time. I have yet to figure out how to make the new engine so that it will co-exist peacefully under the DNN EasyObjects web site, so for the time being I have placed it under a new URL and host header in IIS. There are too many httpmodules and httphandlers to figure out quickly.  :-(

Update (2/13/08): Man, Windows Live Writer makes posting soooooo much easier. I think I'm going to like this switch. All the prior posts have now been migrated, although you may notice that the HTML markup is now a part of the post. I will correct this over the next few days. Also, comments haven't been migrated yet. More changes are on the way!

Next post: The EasyObjects Road Map for 2008.


Tags:
Categories: General
Posted by mgnoonan on Tuesday, February 12, 2008 10:51 PM
Permalink | Comments (3) | Post RSSRSS comment feed

WANTED: Beta testers for EO2

OK, enough excuses and delays, I'm tired of sitting on this code! It's time to get some beta testers for EO2 and the various databases that I have added into the mix. Specifically, I am looking for beta testers for the following platforms:

  • MySQL 5
  • Microsoft Access
  • Firebird 2

I have a good grip on SQL Server and Oracle, so I'm not asking anybody to test those. These libraries are not yet ready for release, so do not sign up to be a beta tester hoping to get your current project completed. Only apply if you are serious about doing some testing, both of the full EO2 and one of the other drivers. I will probably limit the number of testers so as not to become an administrative burden, but we'll see what the response rate is.

There are some quirks to running these libraries, which I will go over in detail with each of the testers. There is a source code change to the Enterprise Library as well, which will no doubt make things interesting.

Contact me through the EasyObjects site to sign up to be a tester, and be sure to include which databases you are interested in testing.

Note: these libraries will not work with the EO2 Free download.


Categories: EasyObjects
Posted by mgnoonan on Monday, December 10, 2007 11:43 PM
Permalink | Comments (2) | Post RSSRSS comment feed

Updated EO2 download for the Enterprise Library 3.1

I know, I know, I promised more updates, but life has conspired to keep me away from EasyObjects lately, and I'm paying the price for it.

But I did finally get a moment between projects to catch my breath (and some sleep!) and I was able to cross one thing off my list: updating the EO2 download for the Enterprise Library 3.1. I left the old EL 2.0 download as well, so users can choose which version to download.

The new download also includes a fix to the C# Business View template, which was generating some incorrect code for columns of type Byte. The fix is also available for download from the MyGeneration template library. You can use the web update feature in MyGen to get the latest.

Now, if I can motivate myself this weekend, I will get the tutorials updated for EO2, since they are way, way, WAY out of date!


Posted by mgnoonan on Saturday, December 08, 2007 11:35 PM
Permalink | Comments (2) | Post RSSRSS comment feed

New look for the website

Check it out. It's a new update to a DotNetNuke skin by Evan O'Neil (who makes awesome skins, btw).

Tags:
Categories: General
Posted by mgnoonan on Monday, July 09, 2007 6:43 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Breaking compatibility with the Enterprise Library

Hello again. First off let me re-introduce myself. I'm the guy who, a long time ago, used to run this web site. I was even known to post on this blog from time to time. Hard to believe, I know.  Laughing

OK, humor aside, it's been quite a while since I posted, mainly because I was on this killer project that just about absorbed all of my nights and weekends for 8 months. So feeling somewhat burned out, and not really having any energy, I just couldn't bring myself to do anything useful for EasyObjects during this period. BUT...

That project is now over, and I have had some time to recover (and sleep!), so now it's time to get back to the business at hand! I have a lot of things to cover, but I'm not going to try to catch up all in one blog posting. Instead I will focus on one item and cover the rest in the next few posts. Here are the topics, in no particular order:

  • Enterprise Library 3.0, and 3.1
  • Other database providers (specifically Access, VistaDB, MySQL and Firebird)
  • The EasyObjects.NET "Store"
  • LINQ and Orcas
  • Design-time databinding
  • Signing the EasyObjects DLL
  • Breaking compatibility with the EntLib

Now, as you have probably guessed by now (from the title of this post), we'll be tackling the last item first.

To start with, a little history: in the Enterprise Library version 1.1 (June 2005), there was a function called GetDataAdapter() that was used mostly internally to create a database-specific data adapter. For example, a SqlDbAdapter for SQL Server, or an OracleDbAdapter for Oracle. In this version of the EntLib, GetDataAdapter() was defined as an abstract method. It didn't really expose the adapter directly to an outside calling entity (such as EO), but that's not such a big deal, really, because EO 1.x doesn't directly use the data adapter. It calls UpdateDataSet(), which eventually creates the adapter in order to do the update.

But this functionality changed drastically in the EntLib 2.0. Now the function is no longer abstract, they define the data adapter in the base Database class.

You may now be asking, why is this important? As it turns out, SQL Server and Oracle are almost unique in one respect when compared to other database engines: they both allow developers to submit multiple SQL statements in the same command. For example, if I want to get the value of an IDENTITY column after I insert a row, I can do it in one step on SQL Server:

"INSERT INTO [Customers] (c1, c2, ...) VALUES (@p1, @p2, ...); SELECT @id = SCOPE_IDENTITY();"

You just define the parameters @p1, @p2, etc. as INPUT and the ID parameter @id as OUTPUT, and you can get the IDENTITY value right away. The problem is, this simple example ONLY WORKS IN SQL SERVER AND ORACLE. Almost every other database that I have run into so far does not support running multiple queries in the same command.

(Note: before you Firebird people start sending me emails, yes I know about the batch command object in Firebird. All that does is submit multiple commands for you, they each have their own FbCommand. It does not run multiple statements in a single command object.)

Lacking this ability to get the IDENTITY value back after an INSERT presents quite a challenge when supporting other databases. That really leaves only a couple of solutions: use stored procedures or try to figure out how to retrieve the data from the new row in the data adapter's RowUpdated event (see? I told you there was a connection!).

Now, MySQL v5 and Firebird support stored procedures, so that's one work-around for those platforms. But what about MS Access? The knowledge base has an article that says that the only way to retrieve the last inserted IDENTITY value is to capture it in the RowUpdated event. OK, that means we need to wire up the event after the data adapter is created.

So I created the MSAccessDatabase class, inherit from Database, and add an override method for GetDataAdapter()...

Except that you can't override that method. Well, crap. I tried various methods of getting around the problem, but without success. So my last, and worst, choice was to modify the Database class in the Enterprise Library so that we can add support for these other databases.

Those of you that have followed the EasyObjects development path know that I do not take this course lightly. Modifying the core EL code is a serious step, especially now that Microsoft distributes the signed versions of the library. But it is my belief that it is necessary, and I have submitted a request to the Patterns & Practices team to change the code in the official distribution.

In the meantime, I have initial versions of Access, Firebird and MySQL providers working for EasyObjects. But more on that in a later post. It's good to be back!


Posted by mgnoonan on Sunday, June 24, 2007 1:00 AM
Permalink | Comments (4) | Post RSSRSS comment feed

Calling a stored procedure using the DAAB

It seems to me there are more than a few on the Enterprise Library forums (http://www.codeplex.com/entlib/Thread/List.aspx) about how to call a stored procedure using the Data Access Application Block (DAAB). And every once in a while the question of how to get a return value from a stored procedure surfaces.

Since it's in my nature to be a problem solver, I have pushed out a couple of templates to the MyGeneration template library that will generate the correct DAAB code for you, one for VB and one for C#. The templates handle the following situations:
  • Load the business entity -or- return a DataSet
  • Execute only
  • Return a DataReader
  • Return a RETURN_VALUE
The templates do not gaurantee perfect code for every scenario, but at least provide you with a great starting point so you don't have to code the whole thing from scratch. It will automatically detect parameters and their input/output status, a return value if you request it, and add the correct parameters to the procedure and method signature. Checking the Static (or Shared in VB) option will generate proper DAAB code, unchecking it will generate the correct calls for an EO business entity.

It's a great timesaver when you are reverse-engineering an application with existing stored procedures that you have to call (I have been using it to add EasyObjects to the TimeTracker project from www.asp.net). I also use it to generate quick code examples when people ask "How do I call this stored procedure?" on the EntLib forum. People are sometimes shocked at the answer, either they missed something simple in their code, or they can't believe how easy it is.

To me, this is yet another example of why you should be using code generation as a part of your development methodology. It gives you and your development staff (no matter how large) a consistent and repeatable process for creating data access code, while at the same time increasing productivity and reducing errors. And hey, as long as you're checking out code generation, maybe give EasyObjects a spin, too?  ;-)

Next on my list is a template for usage with the ObjectDataSource in ASP.NET.

Invoke a stored procedure - C#
http://www.mygenerationsoftware.com/TemplateLibrary/Template/?id=523a2083-1ca5-4dc9-a0c8-769b452c71e0

Invoke a stored procedure - VB.NET
http://www.mygenerationsoftware.com/TemplateLibrary/Template/?id=13696b88-9b79-402b-87c7-f87f42a7cfbb

Tags:
Posted by mgnoonan on Thursday, February 08, 2007 11:50 PM
Permalink | Comments (4) | Post RSSRSS comment feed

Yet more errors

When doing a release, any release, I try to have a repeatable process in place so that if something goes wrong, I don't have to go back and re-assemble all the files. To do this, I use WinZip 10 with their new "job" files. It allows me to specify files and folders to include and exclude, as well as FTP the finished zip up to the server. Nice and neat, and it saves me a lot of time.

But in this case, it also got me into trouble. It turned out the job file was excluding files in the Configuration folder of the EasyObjects project. So everytime I was rebuilding the zip file, it was excluding a handful of necessary files in order to compile the EO DLL (as you may have noticed). Yikes!  :-O

In order to combat this type of failure, I will add an intermediate step into my release process that unzips the finished zip file into a temporary area, attempts to build the DLL, and fails out if there are any errors. It shouldn't be too hard to write a batch file or something that will do this.

I have posted the corrected zip file in the downloads area, and hopefully that's the end of the compile troubles.

Tags:
Categories: EasyObjects
Posted by mgnoonan on Wednesday, February 07, 2007 11:59 PM
Permalink | Comments (2) | Post RSSRSS comment feed