Thursday, May 15, 2008

When VS2008 SP1 beta was released on Monday, I was getting ready to head for Toronto to present three sessions at DevTeach which would be on Wednesday and Thursday. One session was on Astoria another touched LINQ to SQL/EF and DataSets and the last was a deep dive into EF with respect to tiered programming.

The new bits would impact these talks, especially the Astoria and deep dive EF talk a lot and I truly did not want to show people what were now incorrect namespaces, classes whose names had changed, Entity Graphs that did not serialize with services, etc etc.

I made a scary decision and took a huge risk. I updated all of my demos to align with SP1 - this  I did on my dev box at home. This was more than a matter of tweaking some EDMX files and changing class names. The tiered applications needed to be completely reconsidered, rearchitected and rewritten. When I had gotten far enough in this process that I was confident I could finish the transition up, I knew it was time to get the SP1 bits onto my presentaiton laptop.

This didn't go so well. I started the install just before I headed off to my user group meeting. Six hours later I returned to see the install failed because the vista windows sidebar was on. This was 10:30pm. I worked at trying to get the new bits installed until 9am the next morning and then had to give up and head for the airport. To be safe, I threw my CPU, which had what I needed, into my suitcase!

At the speaker dinner that night in Toronto, I was offered a VPC by scott Hanselman who is my savior for the month of May. It already had Vista on it, with VS2008, the Service pack and even Fiddler which I needed for the Atoria session. It was a full day since I began this installation. I hadn't slept and I hadn't been able to complete the demo transitions but I was fully committed.

Or perhaps should be committed.

I pushed my EF debugging skills full bore. But there was more to deal with since the VPC wasn't quite the same as my setup. I had to install all of my databases and change all of the connection strings (there were a lot) inthe many many projects for the 3 sessions in addition to running thorugh every single demo to see where things weren't working.

I didn't get everything fixed on  time and had to go into my presentations knowing that I'd have to skip a few demos and hoped that the bulk of the attendees would feel the same as I did about being able to see how things are not how things were. I think the feelings were mixed (sorry to anyone who found my decision not to be the best).

There is still one entity sql query that is driving me nuts. It keeps saying that "customer" doesn't exist, though the query looks at Customers. Almost as though I had cached something.

I got a few hours of sleep, had chocolate and coffee as my critical helpers, bit the bullet and went for it.

But boy oh boy, I'm not sure if I really need this kind of excitement in my life! :-)

I still need to tighten the rest up so I can get the demos up ontot he DevTeach website, but since not many of the session attendees have SP1 installed yet, hopefully they won't mind waiting a few days.

Thursday, May 15, 2008 6:01:32 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [5]  | 
 Monday, May 12, 2008

Along with Soma and others, the ADO.NET team has announced that the next beta of Entity Framework is available with the VS2008 Service Pack 1 BETA bits. The Astoria team already has a list of changes on their blog and there will be one coming for EF as well.

In the meantime....

Never a dull moment. I have two EF sessions this week at DevTeach and have to very quikly overhaul my demos.

Here are some of my notes.

EDMX Changes

Designer section

<edmx:ReverseEngineer /> has to be removed. I guess it was hopeful thinking.

SSDL

New attribute required inside of schema (Provider="System.Data.SqlClient")
These attributes had to be removed: DateTimeKind="Unspecified" PreserveSeconds="true"
ProviderManifestToken Attribute in schema declaration needs to be changed from the version number (eg for SS2005 that was ProviderManifestToken=.09.00.3054 now is ProviderManifestToken=2005.

Designer section is now at the bottom of the file. Nice.

You cannot have both the Design view and the XML view of an EDMX open at the same time.

In the Model Browser window, the XML for various pieces of the model are no longer shown in the tool tips. While there are reasons behind this, I REALLY liked this and am sad to see it go. Now I have to always close the designer and open up the XML and trudge through it if I just want to verify something. Oh well.

Designer Changes

Oh my its pretty! It's cleaned up; the Asscoiation names are no longer clogging up the view, it's more flexible wrt to what's available on context menus and it has some nice shortcut icons for zooming etc.

Update from Model

As per a blog post from Noam Ben-Ami a while ago, this has improved enormously. With some minor excpetions (which I have not experienced) the CSDL stays intact when you update even though teh SSDL will be competely rewritten so any changes there will be lost. If you add new fields to a table in the database, and it's obvious in the model where it should go, it will make it into the CSDL.

Code Generated Classes

Best bet: just delete them and let VS2008 regenerate them.

API Changes that I've experienced so far

It is very nice to have full graphs coming in and out of WCF services. :-)

Believe it or not, I haven't run into anything else so far that has impacted my apps except for the fact that I need to completely rearchitect my WCF solutions now that I have graphs to pass back and forth. Will I get this done before my session on using Entity Framework across tiers on Wednesday? Nothing like being forever behind the 8-ball. :-)

The EntityDataSource control

I am not a big fan of drag & drop, but I'm liking this control so far. Here are some of the things that are winning me over.

Easily use inherited types

Easily do eager loading with the IncludePaths property.
Note: There's a bug which is preventing the combination of eager loading when you are using an inherited types. That will go away with the next available build.

Many opportunities to override behavior. There are lots of events and the most important to me (so far) is the one lets me control what context the control will be tied to. By default, every EntityDataSource spins up its own context. That's not good if you want to have relationship management happening.

Dynamically build queries with the properties or just entier an EntitySQL string as the command text.

Note that the where parameter takes an Entity SQL predicate, just like you would use with Query Builder methods.

That's all for now.

Have fun!

Monday, May 12, 2008 11:49:46 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [3]  | 
 Thursday, May 08, 2008

I have found myself explaining this in conference sessions so I thought I would write it down in my blog.

Entity Framework has a Golden Rule. Though shalt not do nuttin' that the developer has not explicitly told you to do. The lack of implicit lazy loading is one of the more notable (and hotly contested by some) example of this.

But one day when I was coding, Entity Framework did something that I did not ask it to do. I emailed Danny Simmons to tattle on the API. But Danny explained something to me about RelationshipSpan that needs to override the Golden Rule.

I now call it the Platinum Rule. (I learned this pecking order from American Express).

The Platinum Rule is that an object graph (for example when a customer is attached to an order which is attached to some line items) must be completely in or completely outside of the ObjectContext.

The way I discovered it was that I had a Customer that was being change tracked by an ObjectContext.

I created a new order and attached the order to the customer.

But I did NOT add or attach the order to the context.

Yet, the order was suddenly within the context and being change tracked. Why? Because of the Platinum rule. By attaching the order to the customer, I was creating a graph. Since the graph can't have some of its objects in the context and some of its objects out of the context, it has three options.

  1. Don't allow the objects to be connected. (Now wouldn't that tick you off?)
  2. Pull the customer out of the context. (Now wouldn't that really tick you off?)
  3. Pull the order INTO the context.

Okay, works for me.

So this is the same rule that confuses people when they have an object graph that is IN the context and they detach one of its objects. That object leaves the context and "broken"off of the graph. So if you called context.Detach(Customer), then the customer is detached but the Order and its Line Items are still in the context.

You can no longer traverse from the Customer to the Order or from the Order to the Customer.

On the flip side, if you have an object graph that is not being change tracked  - the whole package, Customer, the order and the details and they are all attached to one another, if you attach any one of them to the context, the whole kit n' caboodle gets pulled into the context - because of the platinum rule.

Thursday, May 08, 2008 8:05:42 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [2]  | 

Like Jeremy Miller, who has Transparent Lazy Loading for Entity Framework on his Christmas Wish List, Timothy Khouri does not like the fact that Entity Framework doesn't support Lazy Loading. However, since he really likes Entity Framework, he wrote some code that will enforce Lazy Loading for him. Entity Framework promises not to do anything you don't explicitly tell it to do, so Timothy found a way to keep telling EF to do this for him because that's what he wants.

After looking at LINQ to SQL's Lazy Loading and then bumping into Entity Framework's explicit Deferred Loading, then sorting things out so he understood not only how the two are different but why, he shares his lesson and his workaround in this article: Entity Framework and Lazy Loading

Thursday, May 08, 2008 7:52:18 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [8]  | 
 Wednesday, May 07, 2008

Entity Data Models have a lot of rules. They are necessary for the integrity of the model, though if you are not familiar with depth of EDMs and *why* these rules exist, many of the mapping rules may seem to make no sense when it comes trying to implement them. This gets hairy when you are mapping stored procedures. Roger Jenning's solution is to create stored procedures that will map properly, rather than suffer wtih the ones that already exist.

The first level of using Stored Procedures is that they work very easily for existing entities that are simple, have no EntityReferences (these involve Foreign Keys) , don't involve inheritance and map directly to a single table in your database.

The next is stored procs that map nicely to entities which don't involve inheritance but if your entities have any relationships, you will probably run into a wall with a delete procedure. Here's why.

Stored Procs become Functions in the Entity Data Model. If you want to use these functions rather than the dynamic SQL that Entity Framework will create, it's an all or nothing scenario. You need to map an Insert, and Update and a Delete. (Read procs doesn't come into play here). There are plenty of blog posts and other resources on how to do this including this tutorial I wrote for the DataDeveloper.net site.

If you have a relationship in your entity, you can map that easily enough to a foreign key parameter in the function mappings and this makes sense with Inserts and Updates. With deletes, generally you only have a primary key (eg ContactID) as the parameter for the stored procedure. But here is where the EDM rules come in to play. A foreign key value that is used in a stored proc, would in most cases map to the EntityKey of a navigation property.

In other words, if you have a stored proc to insert SalesOrders, that procedure will have a parameter for CustomerID. The Order Entity this is mapping to has a relationship to the Customer entity and contains a Customer navigation property. The mapping therefore would link the CustomerID paraemter to Order.Customer.CustomerID.

By doing this, you are involving the association that exists between the Customer entity and the Order entity.

The EDM rule is that if you are involving an association in ONE of the function mappings, you have to use it in ALL o the function mappings.

Therefore a stored proc to delete an order, which only has an OrderID parameter will need also to have a CustomerID parameter because you are required to map SOMETHING to the Customer entity.

This then breaks a possible rule. It means you need to go to the dba and beg them to add this parameter into the stored procedure even though it doesn't get used.

The alternative is to just go in and modify the SSDL to trick it into thinking that that parameter exists which will make the model happy and the database won't care at all. IT doesn't ever really get used.

So if the actual stored proc is

PROCEDURE DeleteOrder

@OrderID int

AS

DELETE from ORDERS WHERE OrderID=@OrderID

and the original function in SSDL is

 <Function Name="DeleteOrder" Aggregate="false" BuiltIn="false" NiladicFunction="false"
            IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
     <Parameter Name="OrderID" Type="int" Mode="In" />
 </Function>

You just need to add a new parameter to the SSDL

 <Function Name="DeleteOrder" Aggregate="false" BuiltIn="false" NiladicFunction="false"
            IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
     <Parameter Name="OrderID" Type="int" Mode="In" />
     <Parameter Name="CustomerID" Type="int" Mode="In" />
 </Function>

This is all fine and good until you need to update the model, because the SSDL will lose all customizations.

I keep my customizations listed in a separate text file so that if I must update the model,  I can replace them.

It's not pretty, but when I don't have a lot of customizations, I will choose this over bugging the dba. Okay, in my world, I'm the DBA (how pathetic is that) but I'm trying to think about enterprise developers and real DBAs.

I started out wanting to write about dealing with stored procs for entities that are inherited, but I guess that will have to come later!

Wednesday, May 07, 2008 1:33:03 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Monday, April 28, 2008

EntityStateObjects, to me, are one of the most important little pieces of the EF puzzle. IT is the EntityStateObject that maintains all of the critical info for change tracking. But it's hard to get the big picture of what's going on in there when debugging because all of the important stuff is delivered through methods, not properties.

I wanted so badly to write a debugger visualizer for them but they are not serializable (big pout) so instead, I wrote an extension method that uses a ConditionalAttribute to ensure it doesn't pop up during run time. It's for my book but I didn't want to hold onto it until October when the book should be published.

Since it's not a Debugger Visualiser, I refer to it as a DebugTime visualizer. :-)

Here's what my ObjectStateEntry Visualizer looks like in action:

All of the info is pulled from the ObjectStateEntry. At the top it tells the fully qualified name of the type of the object being inspected as well as the object's EntityState.

Then I use the various methods of the ObjectStateENtry to get the Original Values, the Current Values, the names of the fields and a list of the names of the modified fields.

All of this data I feed into the grid.

If the object is detached, then there is no ObjectStateEntry and the visualizer shows this message when you try to run it:

So enough with the screenshots. Here's the code. And here's a collection of important punctuations for you C# programmers who feel a need to translate

[ ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;  ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;  ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;  ; ; ; ; ; ; ; ; ; ; ; ; ; ;]

 

Imports System.Runtime.CompilerServices
Imports System.Data.Objects

'NOTE: The objects in use here are not serializable so they can't be used
'in debugger visualizers. Instead, you'll need to use them directly, but you can 
'give them a debug attribute so they are only available during debug mode.
<Extension()> _
Public Module Visualizers


  <ConditionalAttribute("DEBUG")> _
  <Extension()> _
  Public Sub VisualizeObjectStateEntry(ByVal eKey As EntityKey, ByVal context As ObjectContext)
    Dim ose As ObjectStateEntry = Nothing
    If Not context.ObjectStateManager.TryGetObjectStateEntry(eKey, ose) Then
      Windows.Forms.MessageBox.Show("Object is not currently being change tracked and no ObjectStateEntry exists.", _
"ObjectStateEntry Visualizer", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Warning) Else Dim currentValues = ose.CurrentValues Dim originalValues = ose.OriginalValues Dim valueArray As New ArrayList For i = 0 To currentValues.FieldCount - 1



'you can get from the ObjectStateEntry into the MetaData which actually comes from the EDM
Dim sName = currentValues.DataRecordInfo.FieldMetadata.Item(i).FieldType.Name Dim sCurrVal = currentValues.Item(i) Dim sOrigVal = originalValues.Item(i)
'nothing like a little LINQ query to find some info Dim changedProp = (From prop In ose.GetModifiedProperties Where prop = sName).FirstOrDefault Dim propModified As String propModified = If(changedProp = Nothing, "", "X")

'the funky property naming in this anonymous type is to get around a wierdness with
'LINQ databinding that only occurs in VB - it alphabetizes the fields
valueArray.Add(New With _
{._Index = i.ToString, ._Property = sName, .Current = sCurrVal, _
.Original = sOrigVal, .ValueModified = propModified}) Next Dim frm As New debuggerForm With frm.DataGridView1 .DataSource = valueArray End With frm.lblState.Text = ose.State.ToString frm.lblType.Text = ose.Entity.ToString frm.ShowDialog() End If End Sub End Module

The form has no code, just a few controls:

I created an assembly for my Entity Framework extension methods and just reference the assembly anywhere I want to use it.

Then when I want to use it, I call it against the EntityKey of an Entity Object:

  context = new AWModel.AWModel.AWEntities();
  cust = context.Customers.Where(c => c.CustomerID == 223).First();
  cust.CompanyName = "JULIE COMPANY";
  cust.EntityKey.VisualizeObjectStateEntry(context);

This has been an enormously useful tool for when I have been presenting as well as just working.

Enjoy!

Monday, April 28, 2008 8:07:48 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Sunday, April 27, 2008

Along with a few hundred other DevConnections attendees, I got a sneak peek of the EntityDatasSource control on Monday during Danny Simmons' Entity Framework Architecture session.

 

I think I paid more attention to the control than what Danny was saying because I was desperate to see how it was set up.

 

Before digging in though, I also wanted to note that the UI of the EDM Designer looks really pretty. I noticed that the association lines/connectors looked different; the whole thing was cleaner looking (were the association names gone?) and the Entities have their own little representative icon now. I can't wait to see this in more detail.

 

The EntityDataSource wizard identifies EntityConnections in the config file and offers those to as choices for building the data source from. Once that is selected, the EntityContainer is also identified, offering the list of EntitySets from the container to use for the data source.

 

Like the LINQDatasource, you have the option of selecting all of the properties at once or selecting specific properties which will perform projection. Like the LINQDataSource, if you project properties, then you won't get a full type back and the data will not be updatable.

 

There was a drop down list below the one where you choose which EntitySet you want to work with but I don't recall what it's name was. Danny did not drop it down. All I can think of that might be there (hopeful) is derived types since they don't have their own EntitySet.

 

Although I don't remember seeing it during the session, Danny did say that you can choose to eager load related data in the same way that you can with the Include method. I don't know how this is done or if it will impact updating, but I don't know why it would.

 

Like the LinqDataSource,  the EntityDataSource performs server side paging, and it does client side caching - of current AND original data. The original data is not stored as complete objects, but the minimal data necessary to reconstruct state when it's time to update. Updates happen, like any other data source, one at a time. So you have to pick an item, edit it and update it.

 

 I've got some of my own examples of using series of entities in web apps which are very different from this. My solution, however, is aimed at a different scenario. Where the EntityDataSource is more scalable because of the server side paging and the fact that it is not caching full objects, my solution allows the user to do a bunch of edits then save them all at once. I keep the objects in the client side cache (I know - horrors! - but it's an option for a developer to choose) and a collection of original objects cached on the server, though it's an application cache, not a session cache.

 

Seeing the EntityDataSource has already given me some ideas of taking my solution and making it more scalable without losing the benefit of the bulk editing.

 

I can't wait to get my hands on the new bits!

Sunday, April 27, 2008 8:20:30 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Thursday, April 24, 2008

This bit me in the butt ... TWICE!

When using WebDataGen so that you can get a proxy class for an Astoria data service, if you are running under UAC, the output file will NOT get created, however the tool reports that the file was created successfully.

I spent a lot of time trying to find the file or figure out what I was doing wrong.

Then a week later, when it was late at night and I was sick so my brain was a little foggy, I had to create another proxy but totally forgot the pain I had gone through previously. It was an hour before I finally remembered that I had to run the command window as admin.

So word to the wise....and I should probably make a not of this in the forums.

Thursday, April 24, 2008 9:55:09 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Friday, April 18, 2008

I was experimenting with creating data services from IQueryables. Rather than use the canonical example of creating a set of 3 person objects on the fly and exposing them, I decided to create a service for my application log. (Not something I plan to expose to the web, just a learning tool ;-)).

I created a wrapper class for the System.Diagnostics.EventLogEntry class because I needed to have an ID field that could be read. Thanks to Jonathan Carter's blog post, I knew that there was no property of the real class that would work, so I needed to create my own class with a valid field for a discoverable identity property.

Having done this, I tested my service which worked just fine:

Since I knew there are  a LOT of entries in my application log file (I don't have a sysadmin to do that maintenance for me) I thought it would be smart to filter the entries by adding /LogEntries?$top=10 to the URI. I wasn't sure how Vista would handle that and wasn't shocked to see in the debugger that the filtering was going to be left up to the dataservice:

It's definitely a huge advantage to be able to expose (or interact with) any IQueryable through Astoria, but don't forget that it's the database that has the query processor. In this case, I was returning 23,000 items to my service to be processed.

If I do the same filter to a service that exposed a database via an Entity Data Model, for example Northwind

http://localhost:55176/DataServices/NWDataService.svc/Categories?$top=10

the query is processed by the Entity Frawework and the filter is part of query sent to the database:

SELECT TOP (10)
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[CategoryName] AS [CategoryName],
[Extent1].[Description] AS [Description],
[Extent1].[Picture] AS [Picture]
FROM [dbo].[Categories] AS [Extent1]
ORDER BY [Extent1].[CategoryID] ASC

Only 10 items are returned for the service to process.

LINQ to SQL will do the same ... i.e. create a filter query that gets sent to the database.

Yes exposing my entire un-maintained application event log is not a real-life scenario and in a real network, I might even use the nice filters that Vista provides for event logs.

But the point is just to pay attention to what you may be asking your service to do.

Friday, April 18, 2008 4:34:50 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 
 Wednesday, April 16, 2008

While this has been an unfolding process on Ruurd's blog and on the CodePlex/EFContrib site, today marks an impressive day in the evolution of the PostSharp4EF project that Ruurd Boeke has been working on.

He has used the available interfaces for IPOCO in Entity Framework to create a tool for using Entity Framework in a way that is more affable to Domain Driven developers.

His solution enables client side classes that are not dependant on Entity Framework APIs and supports a fully disconnected tiered application - the thing we have all been struggling to achieve.

Ruurd also solved the XML Serialization problem along the way, though in the meantime, changes to WCF actually solve the problem across the board for all WCF XML Serialization, including Entity Framework objects. So I'm sure that was frustrating for him to have this announced shortly after he completed that arduous step, but think of how much you learned, Ruurd and how much respect you have earned as well! :-)

Here is short description of the project. You can find much more on the PostSharp4EF project site under the CodePlex/EFContrib home as well as on Ruurd's blog.

PostSharp4EF: Automatically implement IPoco This project uses PostSharp to post-compile your assemblies. When it encounters a simple attribute, it will implement everything needed to use it in EF: Typelevel attributes, EDMscalar attributes, changetracking and default values. This means there are no runtime performance penalties. See Introducing EF Contrib post for more detailed information about this project. The following supporting projects are included as well and will enable the use of full disconnected n-tier usage of your domain objects:

  • Circular Serializer: enables the serialization of object graphs (including circular references) with knowledge of 'original values'.
  • Editable Business Objects: does changetracking and provides the serializer with the correct values
Wednesday, April 16, 2008 5:31:46 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

I've been fiddling some more with mashing up ADO.NET Data Services using popfly.

I started a few months ago then set it aside.

Today, I extended my mashup block which serves up data from Northwind using an ADO.NET Data Service, then hooked it up to a geocoder block to transform city/country to lat/long, then hooked that up to a virtual earth map.

Wednesday, April 16, 2008 2:01:33 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 

This is a little test popfly mashup that I created from an Astoria data service. You can read the blog post about how I created the data source component here.

Wednesday, April 16, 2008 10:56:01 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

On Friday, I did a full day workshop on Entity Framework called Entity Framework 0-60. Well, I translated it into the local measurement and renamed it 0-100 (km).

One of the comments I got back from an attendee was:

"It was a great overview on a really interesting topic. It was a bit more complex than I expected so it was good to get the expert’s view"

"A bit more complex." This is definitely one of the things that makes EF so difficult to teach or to write about. Even in 6 hours there's so much that I have to glaze over. I tried not to linger in introductory information which they can get more easily elsewhere and spent more time teaching some of the things that are not so obvious and harder to grasp. The last 45 minutes was free form as I invited them to pick my brain and take advantage of all that I have learned so far. I plan to do that again in upcoming workshops.

I think one of the critical things I shared with them during the day was something that is also common to any LINQ queries, which is that you can very easily and unknowingly make trips to the database when you think you are just looking at only the cached objects. When I first mentioned this, the room went silent and their eyes got very big, so I realized that I better spend a little more time exploring this than I had planned.

I'm doing this workshop again this coming Sunday at DevConnections in Orlando (still seats available!) and I expect the day to transpire very differently than it did in Sweden this past Friday. I even completely reorganized the slides on my way home from Sweden because I learned a lot from the questions and reactions of Friday's attendees.

Yes, Entity Framework is complex. And, as the day progressed, I surprised myself with how much I have really learned about this technology. And I seem to have a Rolodex in my head with listings of forums threads and blog posts that I frequently referred to which was very handy.

Wednesday, April 16, 2008 9:01:10 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Thursday, April 10, 2008

These things tend to happen when I'm travelling and don't check my feeds for an entire day. I can't say this is a huge surprise since it's very sensible. I'm happy to finally have some tangible news from the team. I'll be happy to share this news in my Entity Framework workshop tomorrow! During the conference I actually had someone suggest that they still didn't believe that EF wouldn't go the way of Object Spaces. Sheesh!

Entity Framework & ADO.NET Data Services to Ship with VS 2008 SP1 & .NET 3.5 SP1

Wednesday, April 09, 2008, 7:02:00 PM | dpblogsGo to full article

It's settled! The Entity Framework (and the Entity Designer) along with ADO.NET Data Services will RTM as part of the Visual Studio 2008 and .NET 3.5 SP1 releases!

Unfortunately, we don't have official release dates at this point, but stay tuned. You'll also want to keep an eye out for the upcoming SP1 Beta 1, which will be your next chance to check out updated bits for both of these products.

Elisa Flasko
Program Manager, Data Programmability

Thursday, April 10, 2008 6:15:00 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [2]  | 

Doug Seven is one of the track chairs for the track that I'm speaking in at TechEd Developer. I was talking to him the other day about finding the line between the "Presentation Zen" type of presentation (where an extreme example would be a slide with nothing more than a smiley face on it) and a presentation that will be useful to attendees (or other downloaders) after the fact that has actual content on it as the presenter is no longer there to fill in the blanks.

He gave me a great suggestion - prepare two decks. take my typical "stand-alone" decks which is very dense, the make a copy of it and strip the copy down. Way down.

So many of the bullet points are things I'm talking about. Why should the attendees need to be destracted by so many details on the deck when I'm talking about them anyway?

But, and here's what's great about this idea - use the dense deck to share with attendees after the fact. All of the details that I talked about are now there right on the deck for their benefit.

I love this idea so much that I did it to my decks for the DevSummit. I have done one of my sessions already using the stripped down deck, then gave the stand-alone version of the deck to the track chair to put on the website.

I'm doing a silverlight talk this afternoon and cut the deck in half and on the remaining slides, removed a lot of content and replaced some of it with images instead. No smiley faces though.

I get to have my cake and eat it to and I think it's a win-win for the attendees during and after the live session.

Thursday, April 10, 2008 6:34:14 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [3]  | 
 Wednesday, April 09, 2008

I'm not a DBA. I've probably said that about 5000 times. So I am often pretty much out of the loop in the world of SQL Server. So, I really embarrassed myself today asking Niels Berglund if he was a SQL Server guy. I now realize that it would be like asking Kimberly Tripp if she was a SQL Server gal.

And because I am also on a mission to make sure that DBAs are at least aware that the EDM and Entity Framework supports stored procedures, I continued to dig my hole deeper by asking him if he knew that. Turns out he did a full day workshop on LINQ to SQL and Entity Framework at DevWeek in the U.K. I didn't know about this when I wrote a blog post about DevWeek.

So I will now be subscribing to Niels' blog along with Bob B's, since I'm always trying to better understand the DBA perspective on Entity Framework.

Wednesday, April 09, 2008 9:00:56 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

I attended Christian Weyer's Astoria sesson this morning at the DevSummit , one of the few not in Swedish that I could understand! In fact, I was surprised to walk into Tess Ferrandez's session and hear her speaking fluent Swedish. it turns out she lived in Sweden for a time.

Christian shared a brilliant quote in his session which was how to explain REST in one sentence. He got it from David Meggison's "REST - The Quick Pitch" blog post.

With REST, every piece of information has its own URL.

I have had to try to explain REST in my own Astoria talks and I am going to adopt this brilliant quote. Thank Christian!

We'll see if Christian survives his stay in Stockholm as he had quite a lot of fun (and it was hilarious I have to say) talking about the World Cup Soccer 2006. Hey, they only beat Sweden by 2 goals!  My only memory of the World Cup was all of the TechEd attendees swarmed swarmed around the many screens at the conference displaying the matches.

Wednesday, April 09, 2008 8:51:32 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Saturday, April 05, 2008

In my previous post, I managed to update a simple model from an existing database. But then I started trying to do things like build my project and ran into so many problem trying to get my simple model to interact with the AdventureWorks database that I finally gave up.

I actually wrote my thoughts on this in a question on the MSDN forum for Entity Framework, with the point of the question being "is there a real example of this? Or is it just a concept that looks good on paper?"

I care a lot about this becuase I have been sharing this concept (which does make sense to me) that the EDMs loose coupling to the database means that you could map the CSDL to different databases.

But the AdventureWorks database just had too many constraints - such as non-nullable fields that I didn't have in my model and I finally gave up because it was forcing me to modify the CSDL and I would also have to add in some business logic to deal with some of these non-nullable fields. And even if I did that, who knows what other problems would pop up?

Update after I gave myself a little time while eating lunch to think about this some more, I crossed out "finally gave up" becasue it's basically not in my nature. I decided to go about this in a different direction with just ONE entity and succeeded by removing the unused non-nullable fields from the SSDL and mapped the entity to Insert/Update/Delete sprocs. All I have to say to myself at this point is "well, duh!" The insert stored proc provides the missing non-nullable fields and the update stored proc updates the modifieddate for me. SO problem solved in a not very realistic example, but I plan to build it up thought not today - I've already invested too much time. There's a lot of flexilibity in the model, but we all still have a lot of learning to do for our various use cases.

You can read my more complete thoughts on this in the forum post and if you want to follow the conversation you can sign up to get alerts on this thread from the MSDN forums.

Oh, and if you've never signed up for alerts before, you might want to read this blog post I wrote last summer: A few MSDN Forums tips (which I learned the hard way - as usual).

Saturday, April 05, 2008 12:47:18 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

When you use the UpdateModel feature of the Entity Framework design tools, the process relies on matching up existing entity names to table names, more specifically name of objects in the CSDL with names of objects in the database.

IF you have selected objects to add and nothing with that name already exists, it will add a new entity in the model, otherwise, it will use the existing entity.

There are changes coming to how this works detailed in this blog post by Noam Ben-Ami.

But I got bit by something that I overlooked which took hours to pinpoint the cause of the problem, so I wanted to share it.

I had created a model from scratch that was a simple, generic commerce app (see image below). I created entities for Customer, Order, LineItem, Address and Product with some properties, entity keys and associations.

Then I linked it up to  a database using UpdateModel to create the SSDL for me but nothing happened.

It took a lot of experimenting before I realized that the problem was that I was trying to add in a CustomerAddress table but I had an association named CustomerAddress. If that had been an entity, it wouldn't have posed a problem. But the wizard did not know how to handle the fact that it was an association and just completely gave up the ghost.

The only problem I see here is that some indication of the conflict would have helped me figure out what was wrong a little sooner, though I don't expect the wizard to overcome the conflict on its own. I did make a note of this in the forums. However, I am putting the info here for posterity in case it's too late to change the wizard for RTM and somebody else gets stuck on the same problem.

Saturday, April 05, 2008 9:28:29 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Friday, April 04, 2008

I've written a set of Entity Framework (and one which is more general for LINQ to Entities and LINQ to SQL) tutorials that are on DataDeveloper.NET Tutorials page.

Most of these are beginner basics. The "101 Tutorials" are designed to make sure new programmers don't get completely lost. So if you need the extra handholding, it's there, if not just skim over it to get to the juicy bits.

The Tutorials so far are:

101 Tutorial:Creating an ADO.NET Entity Framework Entity Data Model

101 Tutorial: Use an Entity Framework Entity as a WinForms Data Source

Many to Many Relationships in the Entity Data Model

Using Stored Procedures for Insert, Update & Delete in an Entity Data Model

Naming conventions in an Entity Data Model: Cleaning up the wizard-generated EDM

Adding items to a LINQ Query of anonymous types - after the fact

101 Tutorial: ASP.NET DataBinding with the Entity Framework

101 Tutorials: WPF Databinding with Entity Framework

Friday, April 04, 2008 2:41:24 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Wednesday, April 02, 2008

The return type of a LINQ query is an IQueryable, even a LINQ to Entities query.

Here is a screenshot of a LINQ to Entities query at design time (code is NOT being debugged).

But when the query has been processed, it's no longer an IQueryable, but an ObjectQuery.

What's going on here?

At design time, the compiler recognizes that it's a LINQ query and therefore assumes the return will be an IQueryable.

However LINQ to Entities queries are sent to ObjectServices which return an ObjectQuery, so after it's processed, it is actually an ObjectQuery.

So, since it's an ObjectQuery after all, wouldn't it be nice to leverage ObjectQuery features like MergeOptions on a LINQ to Entities query? You can!

But how? At design time, the query is an IQueryable, not an ObjectQuery and doesn't have MergeOptions.

No worries. ObjectQuery implements IQueryable.

So you can cast the LINQ to Entities query to an ObjectQuery, set the MergeOption and, as Jeffrey Palermo would say, party on the LINQ to Entities query (though he may not be likely to say that in the context of Entity Framework ;-)).

    Using context As New AdventureWorksLTEntities
      Dim query = From c In context.Customer Where c.LastName.StartsWith("S")
      Dim objquery = CType(query, ObjectQuery(Of Customer))
      objquery.MergeOption = MergeOption.OverwriteChanges
      Dim cust = query.ToList.First
      Console.WriteLine(cust.LastName)
      cust.LastName = cust.LastName.Trim & "___XYZ"
      cust = query.ToList.First
      Console.WriteLine(cust.LastName)
    End Using

Notice that I'm still performing the operations against the  LINQ query after I cast it to the ObjectQuery.

I could also have done something like

Dim custs = objquery.Execute(MergeOption.OverwriteChanges)

Thanks to Danny for reminding me about the casting! The blog post is intended to lock it into my brain.

Wednesday, April 02, 2008 3:44:46 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

I was fiddling with compiled queries yesterday and thought I would share what I saw as results. This is anything but laboratory benchmark testing so take it for what it's worth. I did only a very simple query to start with, finding SalesOrders whose total is greater than a given number.

You can do this with Entity SQL or LINQ to Entities. Here is my LINQ to Entities compiled query:

Dim compQuery = CompiledQuery.Compile(Of AdventureWorksLTEntities, Decimal, IQueryable(Of SalesOrderHeader))( _
Function(ctx As AdventureWorksLTEntities, total As Decimal) _ From order In ctx.SalesOrderHeader _ Where (order.TotalDue >= total) _ Select order)

To interpret this, Compile's signature looks like this:

Compile(list of args, returntype)(delegate)

It takes a list of arguments and a return type then performs an operation (defined in the delegate) on the arguments. I'm defiining this compilation to recieve an AdventureWorksLTEntities instance and a decimal and the return will be an IQueryable of SalesOrderHeaders.

VB
CompiledQuery.Compile(Of AdventureWorksLTEntities, Decimal, IQueryable(Of SalesOrderHeader))
C#
CompiledQuery.Compile<AdventureWorksLTEntities, Decimal, IQueryable<SalesOrderHeader>>

For the delegate, I use a labmda epxression that says what to do with the parameters which is to build the query.

VB
(Function(ctx As AdventureWorksLTEntities, total As Decimal) _
From order In ctx.SalesOrderHeader _
Where (order.TotalDue >= total) _
Select order)

c#
(ctx, total) => 
from order in ctx.SalesOrderHeader
where (order.TotalDue >= total)
select order)

The whole query is tied to a variable

Dim myCompiledQuery=CompiledQuery.Compile(....

Then when I want to run the query, I invoke it and pass in the parameters

Dim AWEntities As New AdventureWorksLTEntities
Dim orderTotal=200
Dim orders As ObjectQuery(Of SalesOrderHeader) = compQuery.Invoke(AWEntities, orderTotal)

The first time the compiled query is run, it still has to compile, but after that it uses the results of the compilation and can swap in the parameters without needing to recreate the generated command tree.

You can see a big difference between running the query without pre-compilation and running it with the compiled query.

Brian Dawson does some more intense testing and compares LINQ to Entities to Entity SQL as well in this blog post. But I just needed to actually do it myself, rather than only reading about it.

LINQ to SQL also has compiled queries. Rico Mariani has a series of posts on this starting here.

Wednesday, April 02, 2008 9:26:41 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Tuesday, April 01, 2008

Entity Framework owes a lot to the feedback of the nHibernate crew who, as Roger Jennings so aptly states, "were responsible for making the Entity Framework folks finally understand what persistence ignorance is all about".

The PI side of EF still has a long way to go, so in the meantime nHibernate continues to get stronger and stronger.

The alpha of a new version that logs over 100,000 lines of code changes was just released.

I know those guys are beyond frustrated with the current state of Entity Framework and the persistence of people like me who are curious about it and continue to share what I learn with whoever wants to listen, rather than just telling them to run away from data centric programming and join the ALT.NET wave. But what can I say. I embrace the options even if I can't become expert in them all.

Anyway, this release is a huge accomplishment and to have it be done with the dedication of what it takes in an Open Source environmnet to roll out a tool that can be used in big enterprise applications is really impressive.

Tuesday, April 01, 2008 8:24:08 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Highlights of this post from Timothy Ng of the VB team:

"Over the last few months, the VB and Data Programmability teams were working on fixing a performance problem with LINQ to SQL (which also manifested in LINQ to Entities). The issue was that LINQ to SQL was generating sub optimal T-SQL queries when the VB LINQ queries included filters over nullable columns."

"The good news is that the LINQ to SQL team has a fix to their code generation to recognize this pattern, and now they emit the SQL code that you would have expected to emit"

"In other words, LINQ to SQL (and LINQ to Entities - we made the same fix there) is now smart enough to pass three-value logic from VB to SQL."

Tuesday, April 01, 2008 5:02:44 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Monday, March 31, 2008

The MSDN forums for data access have been restructured a little.

Entity Framework & LINQ to Entities questions:

The one which has always been under "MSDN Forums » Visual Studio 2008 (Pre-release) » ADO.NET (Pre-release)" has been renamed to MSDN Forums » Visual Studio 2008 (Pre-release) » ADO.NET Entity Framework and LINQ to Entities (Pre-release). It's still pre-release, of course.

LINQ (Released)

While there is still a general LINQ forum under MSDN Forums » Visual Studio 2008 (Pre-release) » LINQ Project General  (Yes, under Pre-Release. I imagine they don't want to lose the content or confuse people by moving the forum), the LINQ "flavors" have now been split up and are in the "Data Platform Development" section.

MSDN Forums » Data Platform Development » LINQ to SQL  
MSDN Forums » Data Platform Development » ADO.NET DataSet (This includes LINQ to DataSet)
MSDN Forums » Data Platform Development » XML and the .NET Framework   (This includes LINQ to XML)
 
Regular ADO.NET (aka "Classic")

1) The above linked ADO.NET DataSet forum is the place to go for all things DataSet.
2) MSDN Forums » Data Platform Development » ADO.NET Data Providers  
"Data platform development using classic ADO.NET (v 1.1 and 2.0) and System.Data namespace."

Monday, March 31, 2008 9:19:13 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Sunday, March 30, 2008

EFExtensions , released on CodeGallery earlier this week by EF team member, Colin Meek, has a lot of brainy goo in it. So far I've looked at the pieces that Colin has explained in his first post (first post ever) about the Extensions. While most of the extensions in the first part of his post are replicating what Object Services does, the last chunk displays the real benefit of having them at hand.

EF Function Imports can handle READ stored procedures that return existing entity sets. At first I was looking at the extensions to see if they can return random objects, but I haven't seen that yet however there's a lot to look at still. (I'm picturing a generic method that reads the columns and creates an anonymous type on the fly rather than having to go through all of the mucking with the model to make this work. Of course, this is for read-only results.)

What Colin's post shows, however is sprocs that return shaped results. A standard function import can't do this...it needs to map to a single entity type.

So by combining a few of his extensions, he is able to extract the different types from the shaped results and mimic the object materialization that happens under the covers in expected scenarios. Additionally, he is able to add these entities manually into the change tracker.

It's pretty sweet and what's funny to me is that I was trying to do something very similar to this on the same day that Colin released the extensions. I had seen them pop into Code Gallery, made a mental note and a quick blog post without digging into them yet, then a few hours later asked on the forums, "Any way to grab sets of (unrelated) entities in one database call? ". Small world, eh? Now that I have a better understanding of some of the extensions, I will have to go back and see if this does the trick.

Sunday, March 30, 2008 8:43:22 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Friday, March 28, 2008

Is Entity Framework right for your Applications? You'll probably want to answer this question before you start digging in deeply to learn this new data access platform that will be released very soon. Does it fit into my architecture? Will my DBA allow it? How will it play with my existing solutions? This BOF is intended as an interactive discussion where there will be plenty of experts in the room to get you started with some important decision making.

It won't happen unless it gets voted for so go vote!

Friday, March 28, 2008 6:57:52 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Roger Jennings wrote a dizzying (in a good way) post about stored procedures that I have not even had the chance to absorb yet but it's about creating database procedures after the fact that can be easily used with the entities and associations defined in your model.

Coincidentally, Noam Ben-Ami wrote a lengthy post on teh ADO.NET Team blog about using the designer to leverage DML stored procedures that already map directly to entities defined in teh CSDL, while the stored procedures might do perform additional functions, such as time-stamp checking.