Saturday, August 30, 2008

For some background, check out a previous post called "Where's my Foreign Key?"

I came across a scenario where I have a foreign key for an entity in the form of an ID. And the scenario is in a web page. I need to turn that ID into an EntityReference, but I don't think that it's fair to ask the UI developer to know enough about EF that they should have to know how to create an EntityKey, much less know about EntityReferences.

Rather than force them to pass the ID up to the business layer, I finally gave in added foreign key support into the entities that I'm using in this web solution.

I've also gotten sick of having to write this code in many other places where I am creating relationships through EntityReferences. Especially when I make typos and then get this error at runtime.

Rather than futz around with a generic solution, I just manually created these keys in the partial classes for my entities.

As long as I was setting the EntityReference, I thought I would let the property provide the key on demand as well.

Here's an example from the Address class.

Public Property ContactID() As Integer
     Get
         If ContactReference.EntityKey.EntityKeyValues.Count > 0 Then
             Return CType(ContactReference.EntityKey.EntityKeyValues(0).Value, Integer)
         Else
             Return Nothing
         End If
     End Get
     Set(ByVal value As Integer)
         If value > 0 Then
             ContactReference.EntityKey = New EntityKey("myEntities.Contacts", "ContactID", value)
         End If
     End Set
 End Property
Saturday, August 30, 2008 2:20:25 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Friday, August 29, 2008

Last Sunday's NY Times contained an article about multi-touch displays. "Turning Point for Touch Screens", which talks about iPhones, Dells' new Latitude and interviews the CEO of WACOM, who put the tablet in tabletpc.

But the only mention of Microsoft was when talking about the lack of software:

That could change if Microsoft delivers on multitouch technology that it has demonstrated and says will be in Windows 7, the next version of Windows, due in 2010. Such a move could galvanize software developers. Microsoft might also be able to spearhead a software standard that makes it easier for touch-enabled applications to work on the myriad kinds of touch technology.

Granted it's not a household item, but I was surprised that not one word was mentioned about Surface computing. This is multi-touch on a big scale with the benefits of WPF and oh so much more behind it. And it's a pretty nice prototype for laptops. Although it's more globally comprehended if I describe a Surface as a giant iPhone, I prefer to refer to iPhone as a mini-Surface. :-)

The Surface computing team already has an SDK - the beginnings of that software standard?  Here is the Surface team's blog if you are interested in the development side.

 

Screen_SnowBoard_00006 (Small)

Friday, August 29, 2008 7:14:24 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

If you create an Entity Key on the fly:

dim ekey=New EntityKey("NWentities.Customer","customerID",1234)

then add it to an object

cust.EntityKey=ekey

and then try to Attach the object to a context

cust.EntityKey=ekey

and you get this error message

The member with identity 'NWentities does not exist in the metadata collection.
Parameter name: identity

It's telling you that you have NWentities improperly cased. In my model, it's really NWEntities.

If you get this error message,

The required entry ''customerID' was not found in the provided input. This entry is required by the key fields defined on type 'NWModel.Customer'

then the issue is that the  property name is cased incorrectly.

You can only guess how long it took me to figure that out. Hopefully this will help someone doing a google search in the future.

Friday, August 29, 2008 11:14:33 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 

This just popped into my inbox. IdeaBlade has released their EF version of DevForce.

DevForce EF is our latest product supporting Microsoft's LINQ and the Entity Framework.  It carries forward most of the features and all of our experience from DevForce Classic dating back to 2001. 

Why so special?

  • Full N-tier support for the Entity Framework (Entity Framework itself is only 2-tier)
  • LINQ for all your queries
  • High performance with client-side caching and asynchronous queries
  • Improved code generation and model management
  • Take the next step towards Silverlight - DevForce EF business objects are reusable in our upcoming Silverlight product

Sure sounds tempting!

Friday, August 29, 2008 6:48:59 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 
 Thursday, August 28, 2008

Because my development machine crashed and burned last week, I had to build up a new box and decided to finally take the 64-bit plunge. Read more here: My first 64-bit computer

 

[A new DevLife post]

Thursday, August 28, 2008 10:14:11 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

I just happened to discover this as I was setting up my new machine and grabbing Reflector off of the web.

It only happened a week ago.

There will still be a free community version but Red Gate will be able to put additional resources behind enhancing this tool that we can't live without.

You can read an with Lutz Roeder and Red Gate's James Moore in this Simple-Talk article, The Future of Reflector. (Simple-Talk is a Red Gate site.)

When asked if he will be involved, Lutz replies: "I will be using Reflector and I’m sure I will be emailing James every so often asking for new features.” LOL. I guess that means he will be a user like the rest of us. :-)

Thursday, August 28, 2008 9:19:40 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

I finally did it. Late yesterday afternoon I had to get away from the computer so I hopped on my bike and headed south. I thought I would try, yet again, to see if I could get up the App Gap again. Having gotten past the first of two critical points last time, I knew exactly what to expect; so when it got extra hard, I knew that it would let up around the next bend. To make a long story short - I MADE IT! When I pushed past the place I gave up last time, I had my head down and was focused on staying upright (that gets hard when you are going 3 mph LOL) and the next time I looked up I was astonished to see that I was just a hundred feet from the parking spot.

Thanks Andrew (who I know will read this) for your advice. I kept my butt in the saddle the entire time until I saw the parking spot, then I got up and used the rest of it up (just because I could).

Plus I *did* suck down a ClifShot before I left; but since it took me 17 minutes just to get to the start of the climb, I think that was long gone by the time I got to the hard stuff.

What a great feeling. I was definitely drained and sat on a rock admiring the amazing view for about 15 minutes before heading down. It's scary and dangerous going down and I didn't want to do that when I was a little shaky and lightheaded. Which I was. Stupid me only bringing water rather than something like Gatorade to put some electrolytes back in my body.

I actually LOVE to go fast and when the road isn't windy with hairpin turns I go for it. It's one of the few times that my excess baggage is a benefit. (I discovered another benefit on a tour through the colorado rockies years ago during a bad rain storm. All of those skinny people were getting hypothermia but not me!) But I definitely brake most of the way down this road. A few weeks ago a bright young star in the cycling world who we are all SO proud of - Anders Newbury , crashed and broke his hip coming down. I kept thinking about that as I descended.

Anyway, now I know I can do it. Which means I can plan rides that go in that direction. Maybe next I'll try one of Andrew Knight's App Gap Ping Pong rides, since the other side is "easier". I remember when Andrew "discovered" that he likes to climb and was pretty amazing at it. Heh.

So I wouldn't say I dominated the mountain, but I did make it to the top...somehow.

Thursday, August 28, 2008 8:20:35 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 
 Tuesday, August 26, 2008

topsearch

In the past 7 days "NHibernate 2.0" brought more traffic to my web site than any other. Oh the irony. ;-)

Tuesday, August 26, 2008 7:41:06 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [2]  | 

faaI have always refused to take on any clients where an oversight or bug on my part might do something like bring down Wall Street or a region-wide power grid.

So with FAA's computer problems this afternoon bogging down traffic at 40 airports across the country, I am happy that nobody can come knocking on my door.

 

 

 

Tuesday, August 26, 2008 3:47:28 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 
 Monday, August 25, 2008

Well it looks like somebody's been playing with my Silverlight Annotation sample that I put on my website . This is the application that is described in my MSDN article, Write On! Create Web Apps You Can Draw On with Silverlight 2. I just realized that the code download does not seem to be on the magazine website. I'm not sure why. The download is not just the samples displayed in the article but the complete application. I'll update this blog post when that gets corrected.

In the mean time I enjoyed seeing some of the clever annotations that have been drawn on the photos in my sample application. The drawings are stored in a database and called up when the image is selected from the listbox on the right. Each new annotation saved will overwrite the last so these beauties will eventually get lost and I wanted to save them.

annofuna

annofunb

annofunc

annofund

Monday, August 25, 2008 8:35:20 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [4]  | 
 Sunday, August 24, 2008

Last night I got to see a live Prairie Home Companion show. They were here a few years ago but I missed it and was so happy to have another opportunity. It has also been raining for about 2 straight months in Vermont (I am not exaggerating) and last night was the first warm, clear and STARRY night in a long time. So it was a perfect night for this. My friend Michaela and I were fortunate to have awesome seats because I bought them online the morning they went on sale (the minute they went on sale to be exact). The show will air on Sept 6th since they started at 8pm not 6 and couldn't do a live broadcast.

It was really fun to see the show in action - Fred Newman, Sue Scott, the amazing musicians in the All Star Shoe Band and of course the man himself. He referred often to how peaceful and beautiful Vermont is and talked so much about the train ride from NY to Vermont that I want to do it now. I've taken that train from NY to Rhinecliff and Poughkeepsie many times when I lived in NY State, but since I've been up here, I hadn't done the longer version.

The performance was at the fairgrounds in Essex Junction, near the train station and it was funny to hear the train whistling during the show as well as the screams of the people on the rides at the fair which just started last night.

They made lots of jokes about the alternative culture and invented the seedy "east Burlington" (people actually smoke cigarettes there! :-)) (which doesn't exist) for the Guy Noir skit. I've never seen video of Keillor doing his Lake Wobegon story telling. He does not use notes or a script. He's doing it from his head. And what amazed me was his ability to start a thread, go off on a tangent and quite a bit later, wind back to the original thread. I think that was especially noticeable to me because I do a lot of public presenting.

He does not stop performing. Even during the intermission he was leading the entire audience in song. Though when others are performing, he allows himself to fade into the background and let them be center stage.

I loved being able to watch Fred Newman at work doing his sound effects!

I can't believe I didn't bring my camera but it was a wonderful and memorable experience.

Sunday, August 24, 2008 9:20:11 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Friday, August 22, 2008

Don't we always learn our lessons the hard way? My development machine was DOA this morning. I learned of a must-have accessory to keep around just in case on days like today and NO it is NOT a bottle of scotch! :-)

Read more...

[A New DevLife Post]

Friday, August 22, 2008 4:32:34 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Thursday, August 21, 2008

There are a number of things in Entity Framework where if you don't know exactly what to expect, you will get bad data.

The lack of implicit lazy loading is one of those things for developers who have come to expect that behavior based on their experience with other ORMs.

That was intentional on the part of the development team.

But here's one that probably wasn't.

David Yack noticed that if you use Include with an explicit cast, the include doesn't work. It doesn't throw an error, just doesn't' do what it should.

Here's the difference

 

from cust in context.Cutomers.Include("Orders")

vs.

from cust as Customer in context.Customers.Include("orders")
(that's: from Customer cust  in context.Customers.Include("orders") for you C# folks)

 

He emailed me last night and asked if I knew of a problem with Include in SP1, but in the first email didn't mention the explicit cast so I was baffled why he was having problems with Include.

Then he emailed back and showed his query with the cast. He had discovered that it was only when he was casting that the problem occurred.

Oooh that's bad. I know that Entity Framework is obsessive in it's explicitness but this seems pretty extreme.

The cast says "I want a Customer" so the results only bring back a customer, not a graph.

The result is that you will get no orders and go on your merry way thinking that there were no orders in the system.

It's really bad behavior because developers will have no clue.

Good work finding it Dave!

Thursday, August 21, 2008 9:16:27 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [3]  | 

I spent about 1/2 hour this morning trying to figure out why I couldn't get at the .NET source code when others have even blogged about new DLLs being available. I finally found the answer in the MSDN forums - apparently the new files aren't up on the servers yet. Read more here...

[A New DevLife Post]

Thursday, August 21, 2008 7:53:46 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Wednesday, August 20, 2008

I've been laying low from a lot of things while working on my book this summer, but I just confirmed two INETA speaking gigs.

The first is only a few weeks away. I'll be doing a presentation on Silverlight 2.0 Annotation at the Western Mass .NET Group in Springfield, MA which should be about a 3 or 3 1/2 hour drive from home. There are three user groups that I can drive to in 3 hours. This one. Montreal and Albany. I am not a big fan of road trips, but I can endure 3 hours ;-) and I have enjoyed speaking at all of these groups.

The second is in mid-December, after I finish up all of my conference traveling. That will be at the Capital Area .NET User Group and I'll be doing an Intro to Entity Framework presentation. Outside of the Vermont.NET group, this D.C. group is the easiest user group for me to go to. I drive 1/2 hour to the airport, take a 90 minute plane ride to Dulles Airport and then the meeting is about 10 minutes from the airport. There are not many airports that I can fly to without a stop over from Burlington Airport (BTV), so this is pretty sweet.

I really do miss speaking at user groups so this will be fun! In my first year as an INETA speaker I did 16 user group presentations. I just needed to get it out of my system, I suppose. And of course, that was before I was trying to write a book. :-)

Wednesday, August 20, 2008 8:15:18 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Prompted by Roger Jennings' post Entity Framework Instantiation Times with a 120-Table Database, but with limited time to do a thorough investigation, I did a quick trial this morning comparing AdventureWorksLT with it's dozen tables/views to another model with about 400.

There are a few up-front costs for querying in Entity Framework. Query compilation is one and another biggie is loading the model into the application cache. Once the model is loaded, it remains in the applications cache and under normal circumstances, won't need to load again. EF only loads the model pieces as needed. In default scenarios, the conceptual layer is first loaded when ObjectContext is instantiated; the store and mapping layers are loaded the first time a query needs to be compiled.

I am starting the stopwatch prior to the instantiation of each context and stopping when the results have been iterated through completely. I ran the tests numerous times with consistent results.

  First query in application Same query in a completely new objectContext, which benefits from the model already being loaded
AdventureWorksLT 1512 ms 36 ms
400+ entity model 4411ms 46ms

The entity queried in the second test is much wider (many more properties) than the entity queried in the AdventureWorks test. The effort of materializing the app. 200 large objects understandably great than materializing the app. 400 smaller objects from AdventureWorks, so I'm not concerned abut the 10 ms difference there.

My recommendation is to preload the model before you need to do any queries.  You can manually load a metadataworkspace or use this lame trick (Quick Trick for forcing MetadataWorkspace ItemCollections to load) to force it to load early in your application life-cycle.

I've gotten some interesting comments on yesterday's post about building models from very large databases: Entity Framework Designer and Large Databases

Wednesday, August 20, 2008 11:17:35 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [2]  | 

Unfortunately, the datadeveloper.net website is "in between hosts" and we are still waiting for the owners of the site to place it elsewhere.

That means that now that EF has RTM'd and a lot of people are suddenly looking for help, the tutorials that I wrote are not there to help out.

I've recovered six of them which I have posted on www.ProgrammingEntityFramework.com/tutorials.

Wednesday, August 20, 2008 7:11:59 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Tuesday, August 19, 2008

The Northwind database has 27 tables and views. AdventureWorksLT has 17. Sound like your database? Probably not.

What have people who have been pushing the designer with databases with hundreds or even thousands of tables & views been experiencing?

According to Noam Ben-Ami who is on the team that works on the designer, the performance for the designer itself should have "typically reasonable" performance for up to "about 120 tables, after which things begin slowing down."

I created a model from a database with about 400 tables & views, still small for an enterprise database.

The wizard itself took about 20 seconds to generate the visual model. And this is not even a very fast machine. Saving the model took about 1/2 minute as it generated the classes.

Visually the designer has tools that make it easier to view a large model and the fact that the association names are no longer displayed is really helpful.

I have seen in the forums and some blogs reports of attempts to use 1000 or 2000 tables in the designer where the wizard failed miserably.

There are also features of the model that are not supported by the tools. You can implement these in the XML, but when you have hundreds or thousands of tables, this could really make you feel a little crazy.

What about API Performance?

Testing the impact of the large model on the API performance feels like a crap shoot to me. I Know that the command compilation has to work through the model, but is that so hard? ANd of course the # of items in the tables you are querying, the # returned that have to be materialized, the structure of the entity or graph being returned also makes a difference and I can see myself getting lost for a whole day or more looking at that.

Tuesday, August 19, 2008 10:22:52 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [6]  | 
 Sunday, August 17, 2008

From Microsoft

Entity Framework Supported Mapping Scenarios
Writer: Asad Khan
Published: July 2008
Applies To: Entity Framework
Summary: This white paper enumerates the supported mapping scenarios in Entity
Framework. It also mentions important design considerations for store schema in
order to deal with advanced mapping scenarios.

Sunday, August 17, 2008 10:03:06 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [2]  | 
 Friday, August 15, 2008

Naturally, these are on my mind because my hand still stings from getting slapped by the runtime when I tried to do this.

LINQ to Entities does not support projecting into known types structures.

Note, I tried this first with a structure, then saw the forum thread which I quoted below that I apparently misconstrued and landed on the wrong  conclusion. The post stopped me from experimenting further. I have since edited the post to be improve its accuracy. Thanks to Larry Parker for pointing out the gap.

If you have a type or struct defined such as:

Public Structure KeyListItem
  Public ID As Integer
  Public Name As String
End Structure

and are doing a query that will project out an ID and a Name, this is the natural way to write the query, given some experience with LINQ to [anything (including LINQ to SQL) but Entities].

Dim custs = From cust In context.Customers _
            Select New KeyListItem With {.ID = cust.ContactID, .Name = cust.Name}

The compiler is fine with this because at compile time, it's merely a LINQ query.

However when you execute this query, you will get the error:

Only parameterless constructors and initializers are supported by LINQ to Entities.

LINQ to Entities can't construct a new KeyListItem structure on the fly with the ID and Name parameters. 

Here's an explanation of why this is the behavior for LINQ to Entities from Sushil Chordia on the DP team (from this forum thread).

The idea of supporting only parameter-less constructor was one of the hard decisions we made as a product team. The main idea with this approach was we shouldn't open up new surface area in LINQ over Entities that is not supported by EDM. EDM in general doesn't allow you to construct in random objects (using the NEW constructor in eSQL). To make it consistent with the whole stack, we decided to implement it like wise. Limiting the constructions only to:
      - Parameterless constructors 
      - Anonymous types (as it’s the only way to do multi-project in LINQ over Entities)

The query will work if you project into a class, not a structure. If you must use a structure then, instead you need to go the long way around with this.

Dim custs = From cust In context.Customers  _
               Select cust.ContactID, cust.Name
   Dim custlist = New List(Of KeyListItem)
   For Each cust In custs
     custlist.Add(New KeyListItem With {.ID = cust.ContactID, .Name = cust.FullNameAlpha})
   Next

Okay, now the next thing you might accidentally try if your mind is wandering is to use custom properties from your partial classes in queries.

In my model I have a firstname property and a lastname property. I got sick of concatenating them, so I cleverly created two new properties in the entity's partial class: FullName and FullNameAlpha. A long long time ago, I got over the fact that I couldn't pull this off in the model and I'm extremely happy that this scenario is being targeted for v2.

So I'm happily coding along and writing a query where I want to return the FullNameAlpha field and sorted.

Because LINQ depends on the compiled classes to let us code with Intellisense, it's fine with me using the FullNameAlpha property in my query

Dim custs = From cust In .Customer _
                   Order By cust.FullNameAlpha _
                   Select cust.ContactID, cust.FullNameAlpha

But of course FullNameAlpha is not part of the model, so when EF tries to compile the query, it throws the obvious exception:

The specified type member 'FullNameAlpha' is not supported in LINQ to Entities.
Only initializers, entity members, and entity navigation properties are supported.

Oops. Yeah, right, I knew that!

So what that means is I still have to freaking concatenate the first name and last name in my query.

But there's another rule to watch out for which is a LINQ rule, not LINQ to Entities. When you create an on the fly property in a projection and your are doing so with a function, LINQ cannot figure out what to call that property, so you must name it as I have done here by using the variable name "fullname".

Dim custs = From cust In .Customer _
                   Order By cust.FullNameAlpha _
                   Select cust.ContactID, fullname = cust.LastName.Trim & "," & cust.FirstName

Otherwise you will get the LINQ error:

(VB) Range variable name can be inferred only from a simple or qualified name with no arguments

(C#)  Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access.

I imagine I'll repeat these errors over and over and have to be reminded by the thrown exceptions over and over.

Friday, August 15, 2008 5:25:31 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [5]  |