Introduction
In this series of blog entries I’m going to take a look at some work I have been doing with the ADO.NET Entity Framework (AEF) (VS 2008, .Net 3.5), comparing it to LinqToSql, finding the odd bits that aren’t as obvious as they seem and basically giving my impressions of working / understanding it…
You can view my other entries here
Part I – Getting Started
Part II – Inheritance
Code Download
The code for the project and the database used in this demo can be downloaded from Here:
Editing and Persisting Changes
Now we have a Database, and it would be good if we could the other parts of data manipulation, Update, Insert, and Delete. And we can. In fact it’s so easy with inheritance that it seems much TOO EASY! But let’s not be churlish and complain because they made our lives easy!
This entry is going to be short because there really isn’t much to tell here! I did a whole bunch of refactoring and adding menu choices to my console app so we can put the UID thru it’s paces, but the code for setting up the menus isn’t important for this tutorial and isn’t detailed in this entry. You can download the source for the project here if you are REALLY interested!
I will cover the important part of our interaction with the AEF here. Quickly here is how the new app looks:
if you select 1 or 2 you get:
The interesting option choices here are of course, 3, 4, and 5: Edit Contractor, Add Contractor, and Delete Contractor
Here are the screen shots for editing a contractor
Since this was a proof of “how” I just made it so you could edit a middle name, and here is the relevant code for doing exactly that
private static void EditContractor ( int userChoice ) {
if ( userChoice > 0 ) {
//try and retrieve the contractor the person selected from the menu
var contractor = data.Contractors( ).FirstOrDefault( c => c.Id == userChoice );
//if we found someone (they put in a valid entry)
if ( contractor != null ) {
Console.Clear( );
PrintPersonInfo( contractor );
Console.WriteLine( " Specify new Middle Name" );
contractor.MiddleName = Console.In.ReadLine( ).ToString( );
mData.SaveChanges( );
}
}
PadDisplay( );
ListContractors( );
HitEnterToContinue( );
}
And the only relevant lines in that procedure directly related to the AEF update process were
var contractor = data.Contractors( ).FirstOrDefault( c => c.Id == userChoice );
contractor.MiddleName = Console.In.ReadLine( ).ToString( );
mData.SaveChanges( );
That’s all that is necessary as far as the AEF is concerned.
Well that seems logical, but you might be thinking Insert will be ALOT harder, because first you have to get an entry into the Person Table before you can add a contractor, right? Well I wasted 15 minutes the first time I tried to code up an insert looking for exactly that pattern. It is even more amazingly easy then you might expect. Here are the screen shots of the process.
Last name is all that is required to make a valid person entry in the person table
Company Name is all that is required to make a valid Contractor entry in the contractor table
Let’s also get the optional hourly rate
And the code that does this is:
private static void AddContractor ( ) {
var newContractor = new Contractor( );
// LastName is in the Person Table
Console.Clear( );
Console.WriteLine( "Specify Last Name" );
newContractor.LastName = Console.In.ReadLine( ).ToString( );
// CompanyName and HourlyRate are in the Contractor Table
PadDisplay( );
Console.WriteLine( "Specify Company Name" );
newContractor.CompanyName = Console.In.ReadLine( ).ToString( );
PadDisplay( );
Console.WriteLine( "Specify Hourly Rate" );
newContractor.HourlyRate = ReadHourlyRate( );
// we add the contractor to the PEOPLE entity set
mData.AddToPeople( newContractor );
mData.SaveChanges( );
PadDisplay( );
ListContractors( );
HitEnterToContinue( );
}
And the Relevant lines of code are:
var newContractor = new Contractor( );
newContractor.LastName = Console.In.ReadLine( ).ToString( );
newContractor.CompanyName = Console.In.ReadLine( ).ToString( );
newContractor.HourlyRate = ReadHourlyRate( );
mData.AddToPeople( newContractor );
mData.SaveChanges( );
And that is just some freaky cool magic!
Notice that I’m adding the Contractor, NOT to the contractors list, but to the People List. This allows the AEF to “figure” out in what order things have to be saved. It is smart enough to add a person, get our reference then it LOOKS at the type of object we are trying to save, and it goes and finds the table used for the derived type and creates an entry in there, updates the reference to the correct person record, and inserts the correct values.
I’ve been thinking / using that construct for a while now, and STILL think it’s Freaky Cool Magic!
Finally Delete, well that’s even easier. Here are the screen shots.
I’m deleting the one I just added
and here is our result
And the code to do this?
private static void DeleteContractor ( int userChoice ) {
if ( userChoice > 0 ) {
var contractor = mData.Contractors( ).FirstOrDefault( c => c.Id == userChoice );
if ( contractor != null ) {
Console.Clear( );
PrintPersonInfo( contractor );
Console.WriteLine( @"Type ""YES"" to delete contractor" );
if ( Console.In.ReadLine( ).ToString( ).Equals("yes", StringComparison.InvariantCultureIgnoreCase) ) {
mData.DeleteObject( contractor );
mData.SaveChanges( );
}
PadDisplay( );
ListContractors( );
HitEnterToContinue( );
}
}
}
And the relevant lines:
var contractor = mData.Contractors( ).FirstOrDefault( c => c.Id == userChoice );
mData.DeleteObject( contractor );
mData.SaveChanges( );
Notice here, I don’t even have to specify what collection to delete the object from, the AEF will figure out what needs to be deleted based on the type. More Freaky Cool Magic!
Well that’s a good starting primer on AEF, Next Tuesday we will look at using Stored Procedures.