For those who haven't heard Visual Studio 2008 has officially been released! That also means that the .net Framework 3.5 has also been released! For those who have done the Beta's there is a couple of method renaming that has happened that will break your bits!
Summary
- To add a record .Add and .AddAll has been replaced with .InsertOnSumbit and .InsertAllOnSubmit on your Linq Table.
- To delete a record .Remove and .RemoveAll have been replaced with .DeleteOnSubmit and .DeleteAllOnSubmit on your Linq Table.
I think I can understand why they made the change. When you had a line that looked like "dbContext.Documents.Add( mydoc );" it never really felt like I was inserting a record into my database (in fact you are not inserting, not yet! Not until you call .SubmitChanges(); on the DataContext. The same goes for the delete. It was never clear if LINQ was going to "notice" the new record and make sure it is properly added to the database.
So here are are some Linq Samples that we all love!
// Insert a new Record
ADCDataContext db = new ADCDataContext();
Document d = new Document() {
Description = "This is a doc",
FileType = "doc",
CreatedDate = DateTime.Now
};
db.Documents.InsertOnSubmit( d );
db.SubmitChanges();
int did = d.ID; // Notice how the document we just added has been updated.
// Updating a record (or multiple)
ADCDataContext db = new ADCDataContext();
Document doc = (from d in db.Documents
where d.ID == 551
select d).Single();
doc.ModifiedDate = DateTime.Now;
db.SubmitChanges();
// Delete a record (or multiple)
ADCDataContext db = new ADCDataContext();
var doc = from d in db.Documents
where d.CreatedDate > DateTime.Now.AddDays(-90)
select d;
db.Documents.DeleteAllOnSubmit(doc);
db.SubmitChanges();
// Many Custom Type :: Select many documents but return specific type
List<Notifications> changeNotifications = (from doc in db.Documents
where doc.CreatedDate > DateTime.Now.AddMonths(-1) ||
doc.ModifiedDate > DateTime.Now.AddMonths(-2)
select new Notification()
{
NotificationType = ChangeNotificationTypeEnum.All,
NotificationDate = doc.ModifiedDate ?? doc.CreatedDate,
Text = doc.Title
}).ToList();
Now I am not much of a low-level debugger type. I've seen people use WinDbg like it was an extension of their hand! I am not one of those people but I would sure like to be. Lately I have been working on a project that does some pretty tricky code hooking of some User Mode API calls in Kernal32.dll. Specifically I was hooking calls to CreateFileA, CreateFileW, DeleteFileA, and DeleteFileW in Kernel32.dll. Everything was working as expected but when I drag a file in Windows Explorer I can see the CreateFile call being made in the Kernel, but I was not trapping those calls.
Of course, I looked in the call stack in Process Monitor, but without debug symbols, this information is pretty much useless. All I could see is that Kernal32.dll called down to a lower kernel call and was eventually caught as CreateFile. Well, I recently tried to get the symbols to work in Process Monitor and ran into some difficulty. First, I needed the latest version of WinDbg installed as it uses the latest version of DbgHelp.dll. Secondly the symbol path (as unusual as it is already in WinDbg) is slightly different. For some reason Process Monitor needs to know not only where the symbols are but also the path to the executables that match those symbols. I had to use the path: srv*E:\Symbols\*http://msdl.microsoft.com/download/symbols;E:\Windows\;E:\Windows\system32;E:\Windows\system32\Drivers
My Symbol Settings
My Stack Trace now shows with symbols
So my problem was that it is really making a call to CopyFileExW which uses the Kernel's CreateFile function as part of the work it is doing. Process Monitor doesn't really know what the "parent" call for the stack is in the User Mode as it is a kernel level hook. So while it looks like the call to CreateFileW in Kernel32.dll should have hooked this call, Kernal32.dll is actually a user mode dll and is just a shim to pass the call back to the Kernel to do the work.
Fun Stuff!