Monday, August 11, 2008

The release of Visual Studio Service Pack 1 today (currently available for MSDN Subscribers to download), marks the RTM of Entity Framework and ADO.NET Data Services. It's been a long haul for EF, initially shown off in early 2006. ADO.NET Data Services, or ANDS as I've seen Shawn Wildermuth call it (though I still call it Astoria) is a bit younger, making its first public appearance in March 2007 at MIX.

So they are finally here. There were a lot of doubting Thomas' in the first year or so of EF, thinking it would go the way of some other projects that never saw the light of day.

Congratulations to everyone in the Data Programmability team for taking this vision and making it real. And this is just the start. The vision for Entity Data Model is very big and there is much more to come for clients of Entity Data Models. And this first release of Entity Framework for .NET developers to use an EDM is just the beginning as well, with  V2 is already in the works.

I also think that today is a good day to give a nod to a man who helped EF get on it's first legs, and you'll find his name as an author of this early whitepaper about EF, Next-Generation Data Access: Making the Conceptual Level Real - Jim Gray.

Monday, August 11, 2008 3:58:11 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Electric Rain is one of the darlings of the MIX conferences thanks to their early adoption of WPF in creating the very cool StandOut application.

Although the company is based on Colorado, Product Design Manager, Nick Petterssen lives nearby, just outside of Montpelier, VT.

Nick is presenting at tonight's VTdotNET meeting and we're really looking forward to it.

Topic: Designing .NET Apps with Style – A StandOut Case Study
Join Nicholas Petterssen, Director of Product Design for Electric Rain, for a look into how design can differentiate your .NET apps with the new developer/designer workflow Microsoft is touting in .NET 3.0 and beyond. Learn what WPF, Expression Blend and a good interactive designer can do for your projects in the “Sexy App” department and experience how the rich media, animation and 3D capabilities of WPF were utilized by Electric Rain in their next-generation presentation software, StandOut.

Monday, August 11, 2008 2:30:06 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

VS2008 SP1 RTM is now on MSDN Subscriber downloads.

It's an 830MB download, unlike the gigs and gigs of the actual product. But of course, it's still pokey because there's quite a bit of competition on the wire!

Two worthy additions:

1) Don't forget that the Silverlight .NET 2.0 Beta Tools for VS will be refreshed shortly. Current bits do not work with SP1. Here is the patch but DON'T MISS Amy Dullard's blog post, Silverlight Tools Must be Updated After Installing Visual Studio 2008 SP1, for information on some issues and non-English versions.

2)If you have previous installations of SP1 betas etc, you'll want to run this "preparation tool" to clean up your system prior to installing the RTM bits.

Monday, August 11, 2008 10:32:57 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 
 Friday, August 08, 2008

Don Kiely has been preaching the evils of Full Trust in .NET, SQL and Windows for quite a while. SO when he saw a question on the ASP.NET Forums on using the Dynamic Data Controls with EF as the data provider that involved a trust issue, he was on it like white on rice.

Dynamic Data with the Entity Framework in Medium Trust

The issue was specifically when you are using a website not a web application and you have the EDMX right in the site. In this scenario, the model files are always embedded into the sites assembly. You don't have an option to build the files externally. In fact, Embed in Output Assembly is the only option for Metadata Artifact Processing.

While one of the suggested solutions was to create the model in a separate dll so that you can build the model files separately from the DLL, Don show's how to easily use the EntityDesignerBuildProvider to get at the files.

Nice!

Friday, August 08, 2008 1:56:18 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Worth repeating from Guy Burstein's blog. I've followed some issues people are having with this on an email list. VS2008 SP1 will release "in about a week from now", or sooner, or later, but it is very close. So hang in there.

 

Sql Server 2008 Visual Studio SP1

Certain SQL Server 2008 features install components that are also part of the release version of Visual Studio 2008 SP1. So, if Visual Studio 2008 without the service pack is installed on your machine, you cannot install SQL Server 2008. If you try to install, you will ran into the following error:

Rule "Previous releases of Microsoft Visual Studio 2008" failed.

A previous release of Microsoft Visual Studio 2008 is installed on this computer. Upgrade Microsoft Visual Studio 2008 to the SP1 before installing SQL Server 2008.

In case you are wondering, Visual Studio 2008 SP1 should be expected about a week from now, so you don't have to wait too much.

Friday, August 08, 2008 1:31:49 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Thursday, August 07, 2008

This may only mean something to about 10 people on the planet, but I thought I'd share it anyway.

If you are using Entity Framework's MetadataWorkspace to dig around in the model's structure, the CSpace (schema from the conceptual layer aka CSDL) is readily available however, the other collections, SSpace (ssdl) and CSSpace( msl) are not loaded until they are needed. Well, trying to read them with the MetadataWorkspace doesn't count as being needed. They are needed during query compilation, then again at object materialization.

Unfortunately, there's not method to just say "hey, get me the MSL schema, please", though there are some factory methods deep down in the API that are a PIA to use.

SO instead, what I've been using is just a quick method that creates an ObjectQuery and then forces query compilation by requesting ToTraceString. Then throw away the query. No need to execute it.

I created this method in a Partial Class for a oarticular EntityContainer class.

Private Sub forceDataSpacestoLoad()
  Dim tracestring  = CreateQuery(Of Contact)("AWEntities.Contacts").ToTraceString  'the ESQL is a shortcut
End Sub

Now when I need to use the mapping or store collections, if the one I need is not loaded, I can force it.

If Not mdw.TryGetItemCollection(DataSpace.CSSpace, mappingCollection)Then
forceDataSpacestoLoad()
End If

Once loaded, ItemCollections stay in the application cache.

You could create something more generic and make it an extension method of ObjectContext. HEre, I just grab a random entity to build a query from and cast the whole thing back to an EntityObject.

   If Not randomentityType Is Nothing Then
     Dim esetName = mdw.GetEntitySetFullName(randomentityType)
     Dim tracestring = CreateQuery(Of EntityObject)(esetName).ToTraceString
   Else
     Throw New InvalidOperationException("Could not force metadata to load")
   End If

Now you'll probably want to know where GetEntitySetFullName comes from. It's one of the many extension methods I've created while writing my book.

Here ya go!

  <Extension()> _
  Public Function GetEntitySetFullName(ByVal mdw As MetadataWorkspace, ByVal entityName As String) As String
    Dim entContainer = mdw.GetItems(Of EntityContainer)(DataSpace.CSpace).First
    Dim entsets = From eset In entContainer.BaseEntitySets _
                  Where eset.ElementType.Name = entityName
    Dim containerName = entsets.First.EntityContainer.Name
    Return containerName & "." & entsets.First.Name
  End Function
Thursday, August 07, 2008 3:54:38 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 
 Wednesday, August 06, 2008

Even though I seem to have gotten it right when I wrote about this in my book (I just checked) in my own memory I have had a misconception about GetObjectbyKey.

I thought that GetObjectbyKey and TryGetObjectbyKey only searches the cache for entities that already have been created. But I realized this morning that if it doesn't find the entity in the cache, it will create a query and go look in the database also.

dim myEntity=context.GetObjectbyKey(myKey)

or use one of the methods for creating an EntityKey on the fly.

Dim cust=context.GetObjectbyKey(new EntityKey("NorthWindEntities.Customers","CustomerID",3)

You can easily make this a generic method if you needed to.

Compare this to a query

Dim cust= (From c in context.Customers Where c.CustomerID=3).FirstorDefault

or

Dim cust=context.Customers.Where(Function(c) c.CustomerID=3).FirstorDefault

Using GetObjectbyKey vs. a query is not just about coding because they work very differently.

When you execute a query, EF will always go to the database first and retrieve whatever it finds. As it's loading the results into the cache, if the entity already exists in the cache, it will refresh that entity based on the MergeOptions.

  • If MergeOption is AppendOnly (this is the default) then the newly retrieved entity will disappear into the ether.
  • If it is OverwriteChanges, then the values from the server will replace the current values of the entity in the cache.
  • If it is PreserveChanges, the values from the server will replace the original values of the entity in the cache. The current values won't be touched.
  • MergeOption can also be set to NoTracking. That's an interesting scenario because it will create a second instance of this object. I'm not sure how I feel about that yet. However, if you already have an entity in memory but not in the cache, GetObjectbyKey will have the same effect. It won't find the entity in the cache and will go get one and put it into the cache - result is two instances of the entity.

So depending on your needs, GetObjectbyKEy (and TryGetOBjectbyKey) is very efficient because it won't go to the database unless it has to, however it won't refresh your data from the server as a query would.

Good to know so I can make the right choice when the time comes.

Wednesday, August 06, 2008 8:05:19 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [4]  | 
 Tuesday, August 05, 2008

I am copying (and slightly modifying so that it is not out of context) a forum post that I wrote to put here in my blog. Here's the original thread if you are interested.

When working with object services, you can query data using  LINQ to Entities or ObjectQueries with Entity SQL.

Unless you specifically use LINQ syntax in your EF query,  it will be an ObjectQuery.

An example.

context.Customers  is an ObjectQuery. The same as context.CreateQuery<Customer>("SELECT c FROM myentitycontainer.Customers as c") or even context.CreateQuery<TEntity>(entitySetNameString) if you want to do this generically as Graham Hay shows earlier in this thread.

from cust in context.Customers blah blah is a LINQ to Entities query.

The first example (return context.Customers) however takes advantage of EF's query builder methods which will literally construct a nice ESQL query and create an objectQuery for you. There are not a lot of ESQL Query Builder methods but some of them overlap with LINQ methods.

Check out the difference here:

var q1=context.Customers.Where("it.FirstName='Julie'")

var q2=context.Customers.Where(c=>c.FirstName=="Julie")

The first uses a query builder method and ESQL syntax in the where parameter, therefore EF will know that you are using the Where Query Builder method, not the LINQ to Entities one. But the second uses a lambda so EF knows that's LINQ.

At run time, after the first line of code has been executed (not the executing the query, just the creating q1), you can debug q1 and see that it is an ObjectQuery<Customer> and that it has a command text value that is an ESQL Query

"SELECT VALUE it\r\nFROM (\r\n[Customer]\r\n) AS it\r\nWHERE\r\nit.FirstName='Julie'"

Because the second query has some very specific LINQ to Entities syntax in it, EF determines that this is a LINQ to Entities query. When debugging Q2, the value of q2 will be an objectQuery<Customer> but the TYPE of Q2 will be a System.LINQ.IQueryable. The CommandText property is empty.

LINQ to Entities and ObjectQuery queries are processed differently as well. The first few steps for each are unique to the query method, then at some point in the query pipeline, they meet on a common path.

Don't discount ObjectQuery as a query option because it is that class that allows you to more readily use generics and build dynamic queries.

To use generics in a real LINQ to entities query, you would probably have to do functional programming.

This is why ObjectQueries are so powerful. You can use generics with them. You can build queries dynamically.

But don't expect to do it using the strongly typed classes. Use CreateQuery or new ObjectQuery and then pass in the generic type (e.g. TEntity) and the Entity SQL string.

Tuesday, August 05, 2008 10:21:07 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Monday, August 04, 2008

This weekend's passing of Alexander Solzhenitsyn prompted me to think about my senior year in college. I was a history major with a concentration in Russian History (and had no clue what a hash table was by the time I graduated). My senior thesis was a comparison of the experiences of political prisoners under the Tsarist regime of the late 19th/early 20th centuries, to those of the political prisoners of the Stalinist era. The irony is that it was the political prisoners of the first that led the revolution which over time, resulted (indirectly) in Stalin coming to power. And Stalin cast a much broader net when defining his enemies.

My research mostly took the form of reading published diaries. Many of them. Solzhenitsyn's writings about the labor camps was definitely an invaluable resource.

So if you can imagine my days and nights for months and months spent in a dark corner of the library reading these harrowing personal accounts.

In addition to my other classes, that semester I was the photo editor for the college yearbook.  When I wasn't in classes and wasn't reading the depressing diaries, I spent endless hours in a darkroom processing film and printing  photos. The only radio station that I could receive in the darkroom (remember this was the early 80's so our media options were pretty limited) was one that played golden oldies from the 1940's. This was apropos since the this is the time of the Stalinist labor camps.

So all in all it was a very dark 4 months in my life, not only literally dark, but filled with doom, gloom and hopelessness and living in the past.

What I never knew until his death yesterday, was that he, too lived in Vermont. From 1976 to 1990 when he returned to his homeland, he lived in the tiny town of Cavendish in Southern Vermont.

Monday, August 04, 2008 7:51:11 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Saturday, August 02, 2008

sampleappI remember seeing WPF/E, the early version of what was to become Silverlight, at Microsoft a few years ago, then running over to the building where the TabletPC team lives and asking if the WPF inking features were going to be in Silverlight. As you may or may not know by now, the answer was yes and it is the InkPresenter control in Silverlight that enables drawing in Silverlight apps. I had been doing a lot of work with Ink on the Web and was frustrated by the limitations and challenges of dealing with ActiveX. Putting the capabilities into Silverlight not only mean very easy deployment, but it removed the restriction for TabletPC O/S or even a Windows O/S, as well as a dependence on Internet Explorer.

I have presented this technology at various conferences - generally to a small audience. I am always surprised that more people aren't interested in it. Are we really just Tablet PC Freaks?

Even the Silverlight books don't devote very much time to the InkPresenter.

Well a few more people are going to be exposed to this now because this months MSDN Magazine (August 2008) has an article about using the InkPresenter that I wrote. (The issue features a bunch of Silverlight articles and an Astoria article too!) The article not only shows how to get the InkPresenter to do it's inky thing, but also how to take advantage of web services to persist and retrieve drawings as well as to do hand writing recognition. The latter, as I discovered when I put my sample up on my web site, requires that the service be hosted on a computer that has the Recognition Engines installed. If you have a TabletPC or Windows Vista, they are already there. Otherwise, you need to install them on the host. Unfortunately, my own web site is on a shared server, so installing the reco engines is not an option.

I've also learned that even though the reco is in Vista, and the Speech Engines made it into Windows 2008 Server, the hand writing reco engines did not.

The article (and the sample) uses Silverlight 2.0, LINQ to SQL, LINQ to XML and WCF Services so it was fun to use so many new technologies. I originally did the work in Silverlight 1.0 with Javascript so it can be done, just a little harder. I guess the next step would be to replace the LINQ to SQL and WCF with Astoria but that's for another day.

You can get the engines here: MS Windows XP Tablet PC Editions 2005 Recognizer Pack.

The article: Write On! Create Web Apps You Can Draw On with Silverlight 2

The sample application for Silverlight 2.0 (without the recognition until I move the WCF Service elsewhere) : http://www.thedatafarm.com/Silverlight/AnnotationMSDN/.

Unfortunately, drawing is not one of my skills, so some of the screenshots in the article are laughable, but hey, whadya want? :-)

(Oh and I'm not responsible for that very first sentence. But as Kathleen says: We Don't Publish Words, We Publish Ideas - Get Over It)

Have fun!!

Saturday, August 02, 2008 12:12:37 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 
 Friday, August 01, 2008

dragon1

This weekend is the third DragonHeart Dragon Boat race on Lake Champlain in Burlington. This will be my second year paddling in the event on a team called the Dragonflies, made up of 20+ friends - all women. There are 80 teams in the event. Most of them are community teams that have no more practice time than the single practice paddle that the event organizes in July, so we're mostly just winging it and not really that competitive. There are amateur teams that own their own boats and participate in races all over the world. We'll even have to compete against them in our first two (and maybe only two) heats.

The real DragonHeart teams are made up of  breast cancer survivors. The event is a fundraiser for their organization and another organization of their choice, which is Vermont's "Cancer Patient Support Program’s Emergency Fund" this year.

It's an amazing day and there are over 2000 participants (80 teams * 20 per team) and thousands of spectators. Hopefully we'll luck out with the weather.

Our team's first paddle is at 9am. Early pearly.

Friday, August 01, 2008 2:45:34 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 
 Wednesday, July 30, 2008

I have been writing gobs of Extension methods for entity Framework through the course of writing my book.

I was inspired by this forum thread to create extension methods to overload existing methods in the APIs.

One pattern that was annoying me was that frequently when I'm using the GetObjectStateEntries method of the ObjectStateManager, I want to filter on a type. It only meant building a linq expression with the method in it

Dim CustomerEntries= From entry _
                                    In objStateMgr.GetObjectStateEntries(EntityState.Added Or EntityState.Deleted _
                                          Or EntityState.Modified Or EntityState.Unchanged) _
                                    Where entry.Entity.GetType Is Customer

So two things about this were bugging me.

The first is I always have to list out all of those entries. Sometimes I only want one or two, so it's good to build the list.

The second is that I always have to write a query.

So, I created a few overloads to the method.

The first takes no parameters, and returns all of the entries, regardless of EntityState

<Extension()> _
Public Function GetObjectStateEntries(ByVal osm As Objects.ObjectStateManager) _
   
As IEnumerable(Of Objects.ObjectStateEntry)
  Dim typeEntries = From entry As Objects.ObjectStateEntry _
                  
In osm.GetObjectStateEntries(EntityState.Added Or EntityState.Deleted _
                      Or EntityState.Modified Or EntityState.Unchanged)
  Return typeEntries
End Function

Now I can just call GetObjectStateEntries and get all of them without having to specify the four entity state enums.

The second returns all objects of a particular type. Having the overload for the generic type is more discoverable for people like me.

<Extension()> _
Public Function GetObjectStateEntries(Of TEntity)(ByVal osm As Objects.ObjectStateManager) _
    
As IEnumerable(Of Objects.ObjectStateEntry)  
  Dim typeEntries = From entry As Objects.ObjectStateEntry _
                    In osm.GetObjectStateEntries(EntityState.Added Or EntityState.Deleted _
                      Or EntityState.Modified Or EntityState.Unchanged) _
                    Where entry.Entity Is TEntity

  Return typeEntries 
End Function

Now I can get all entities of a particular type without having to build a query.

GetObjectStateEntries(Of Customer)

The last takes the EntityState parameters and filters on a particular type.

<Extension()> _
Public Function GetObjectStateEntries(Of TEntity)(ByVal osm As Objects.ObjectStateManager, _
         ByVal state As EntityState) As IEnumerable(Of Objects.ObjectStateEntry) 
  Dim typeEntries = From entry As Objects.ObjectStateEntry _
                    In osm.GetObjectStateEntries(state) _
                    Where entry.Entity Is TEntity
  Return typeEntries
End Function

So I can use GetObjectStateEntries it's "normal" way, except I can include the type as well as filtering on state.

GetObjectStateEntries(Of Customer)(EntityState.Unchanged)

(These are in Chapter 14 along with their C# versions. :-))

Wednesday, July 30, 2008 9:21:05 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Monday, July 28, 2008

My friend's husband is a biologist and researcher at Cornell's Ornithology Lab and pretty well known in his field.

NPR played some clips that he recorded in Guatemala of Howler Monkeys and Toucan's on their feature, Sounds from the Wild. Cool.

Monday, July 28, 2008 12:08:54 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 

Yesterday I made my third attempt of the summer to get up the the 2.75 mile climb of the App Gap. I have to ride uphill 3 miles just to get to the "starting point".

Here's what the elevation looks like from the starting point to the peak.

The first arrow is where I've bailed previously (twice). The second is about where I got to last night (2.5 miles). The yellow line is the peak. You can see that the last bit is a freaking wall.

appgap

I almost bailed at the same spot again last night but goaded myself to the next sign (50 ft away) then to the end of the guard rail (another 100 ft) and then to the picnic tables (another 200 ft). Then once I got past the picnic tables, it eased up again and I got all the way to the last wall, but there was just no way I could do the last little bit. Now that I realize that it gets easier past that first spot, I can definitely push myself through it again.

However, since I had started out hoping to just get past my last bail point and maybe to the picnic tables, I was surprised to get as far as I did. I wasn't the least bit disappointed not to get to the top because that wasn't my goal.

On the way up, I saw my neighbor, Joe, flying down on his bike. He does the gap ride all the time. It's not big deal at all for him. :-) It's his little ride for when he doesn't have time to go out for a real ride.

One of the things that helped me was deciding to just go right up into my granny gear at the start - save my strength, not my gears.

Okay back to work.

Monday, July 28, 2008 9:32:03 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [2]  | 

While I continue to enjoy being at home in Vermont for the whole summer, I have to look past this fantasy to the reality of my upcoming travel where I get to share the Entity Framework (and Silverlight) love around the world. I have yet to get this all onto my website schedule.

Here's what's on my schedule:

I'm also planning to attend Microsoft's PDC 2008 in Los Angeles

Then I will rest up for the winter in Vermont. :-)

Monday, July 28, 2008 7:22:48 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Saturday, July 26, 2008

There are two web apps based on mapping APIs - one uses Google and the other uses Virtual Earth - that I use frequently. It's a long way from what you could do with Virtual Earth when I started dabbling when it first came out. Read more.

[A New DevLife Post]

Saturday, July 26, 2008 7:00:49 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Mike has posted a bunch of ADO.NET Data Services videos up on Channel 9.

Even though I haven't had a chance to check them out yet, it's easy to presume that these are going to be as great as all of his other screencasts.

http://channel9.msdn.com/tags/UK

He says there are more to come.

Enjoy.

Saturday, July 26, 2008 12:11:01 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Friday, July 25, 2008

I learned a neat ESQL trick from Danny Simmons today.

The most basic Entity SQL expression is one that would simply query for a single entity with no filters, no projection etc.

context.CreateQuery<Customer>("SELECT VALUE con FROM MYEntityContainer.Contacts AS con")

You can actually express the string using only the target collection:

context.CreateQuery<Customer>("MyEntityContainer.Contacts")

and EF will build the same command tree as it does for the first expression.

Friday, July 25, 2008 8:45:30 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Software Developer

Vertek Corporation, a leading provider of telecommunications services located in Colchester, Vermont is seeking a Software Developer to join our growing Software Development team.

The Software Developer will support our existing products and help Vertek build our next generation workflow platform which leverages Red Hat’s jBPM workflow engine with a Google Web Toolkit (GWT) Web 2.0 presentation framework. The ideal candidate will have full/hands-on SWDLC experience designing, building, testing, deploying and supporting n-tier applications. Candidates should have experience with two or more of the following technologies: GWT, JBoss, JUnit (or NUnit), Hibernate, Subversion, .NET, Business Objects (universe creation). They should have hands-on experience with all of the following: n-Tier development, SQL Server 2000+ and/or Oracle 10g, Java, Eclipse, Ant and web development. Experience developing large scale/enterprise applications in a Continuous Integration environment is a plus.

Required experience and education: 1-3 years, bachelor’s degree in computer science or related discipline (relevant co-op experience may be applied). Java, Oracle and/or Microsoft certifications are a plus.

E-mail resume to: HR@Vertek.com

Friday, July 25, 2008 8:20:50 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Kathleen Dollard is building a list for C# devs who are going to be building projects in VB. Read more

[A New DevLife Post]

VB
Friday, July 25, 2008 2:14:49 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [2]  |