Rants Tagged with “ADO.NET”

1  2  3  4  5  6  7  8  >  >>  (Total Pages: 8/Total Results: 73)

Not at the PDC? Come Watch Me Talk about ADO.NET Data Services

Today at 3pm CST (4pm EST, 1pm PST) I will be doing a LiveMeeting talk on ADO.NET Data Services. If you are not at the PDC this week, drop by NotAtPDC.com and check out my session!

First Impressions of Oslo

Silverlight Logo

I've spent a number of hours since I downloaded the Oslo SDK to look around. In this post I want to tell you what I've found out.

Oslo is a funny beast because its multi-layered. With only a couple of hours on its hard to even know if my assumptions are all correct. I am sure we'll see in comments if I am far off or not.

As I read stories about Oslo before I was able to look at actual bits, I felt confused. I heard two stories: "Oslo is about Modeling and Model Driven Development"; and "Oslo is about building Domain Specific Languages". So which is it?  Both.

I used to be "The ADO Guy" so lets start with the modeling:

Modeling Features

Oslo's Modeling Platform is a layered technology that is made up of several pieces:

  • Quadrant: A Visual Designer for flowchart-like models.
  • The "M" Language: A Textual DSL that supports creating your own system models or extending the built-in models.
  • "Oslo Repository": A Database for storing models to be used at design-time and runtime.

In the SDK that I have played with, Quadrant isn't included (it is in the Oslo Virtual PC that is on the PDC attendee hard disk) so I haven't had any opportunity to look at that. What I did spent time with what the "M" language and a simple editor for it that is included called "Intellipad". The "M" language allows you to define quite a lot about an application, but the only part I played with so far is the modeling of data. Using Intellipad I attempted to model some Video Games data that i've been playing with in demos and the Silverlight 2 workshop.  Intellipad simply lets me define the types including the data extents:

What is particularly interesting here is how the "M" language can be used to generate SQL scripts to create the storage.  In Intellipad we can show a panel that shows the generated SQL:

(Click for a larger view of the SQL)

This is enough to keep my interest. I like where this is going but until I can really see what Quadrant does its hard to see how this fits into the bigger picture. So now lets look at the Domain Specific Language underpinnings:

Domain Specific Language Features

Of even more interest to me is the infrastructure that they used to build the modeling features. The "M" language is actually a Domain Specific Language called "MSchema" built with the Oslo Domain Specific Language ecosystem. MSchema defines a "little language" that is used to define models. But how is MSchema defined?  It uses a lower level Domain Specific Language called MGrammar. MGrammar defines a "little language" for defining Domain Specific Languages. Beneath both of these is another language called MGraph that I haven't totally grok'ed yet. 

I haven't had time to try and build one but in the SDK is a cool small example called "Song". This small Domain Specific Language defines a "little language" that supports songs as a list of notes and rests, for example:

Music
- - - D
C C# F G
E E - D
A E - E
G F - E
D C D E
A E D D
D E A C

More importantly, we can use the MGrammar to define what this language is composed of:

In most other instances I've been pushed to think of Domain Specific Languages being build either in a language (usually something like Ruby with lots of Macro'ing) or in data structures (like JSON or XML) since both of these ideas allow for avoiding building my own parser. The Oslo stack changes this idea for me an really allows me to define small languages without the need for these scenarios.

You may be asking how Domain Specific Languages impact you as a developer though? I recently gave a talk at the Atlanta .NET Users Group to try and cement some of these ideas. My overarching idea is that by writing "little languages" that use the same semantics as the domain, we can 'code' the intent of users in a domain (e.g. a business) and then the domain's stakeholders can validate the 'code' since its written in the language of the domain. But that's a story for another post.  Understand that I see Domain Specific Languages as a powerful idea for everyday programmers, not just academic scenarios.

This is just a tiny taste, but so far I am incredibly intrigued by the possibilities of Oslo. In the coming months you can expect to hear quite a bit from me about this topic.  But I am no expert.  I started down this Domain Specific Language path by trying to read and study information on the topic. By far the best thing I ran across was this great video by Martin Fowler that everyone should watch...its well worth your time:

Since Martin Fowler is important in this space, I was thrilled to see he was shown a preview and had time to give his first impressions as well:

What do you think?

ADO.NET Data Services and TimeZone

Silverlight Logo

There is a known problem with ADO.NET Data Services today that is important if you (or your server) lives in specific timezones.  The problem is associated with the way that the Silverlight Data Services Library constructs their URI for searches. 

The problem surfaces if you do a query that has a DateTime comparison in it. For example:

var qry = from o in ctx.Orders
          where o.OrderDate <= dt
          select o;

This query generates the following URI in the EST timezone in the US:

http://.../ProductService.svc/Orders()?$filter=OrderDate le datetime'2008-10-13T00:00:00-04:00'

This works great. The problem is that in other timezones (e.g. Bulgaria) where its forward of Greenwich Mean Time, so the UTC date is +03:00 like so:

http://.../ProductService.svc/Orders()?$filter=OrderDate le datetime'2008-10-13T00:00:00+03:00'

Because the "+" isn't URL Encoded, it becomes a space which makes the date incorrect.  For now you can convert the date to universal time but that's a hack at best:

var qry = from o in ctx.Orders
          where o.OrderDate <= DateTime.Today.ToUniversalTime()
          select o;

It works but its a hack.

Silverlight and ADO.NET Data Service Operations

Silverlight Logo

In building my Silverlight RC example using ADO.NET Data Services for Entity Framework and NHibernate I ran into what I think is a common pattern.  I am writing an editor for XBox game data. The model for this data uses decorator tables in the database which are modeled as a common "Product" class and derived "Game", "Console" and "Accessory" classes.  In the application I am using paging to only look at fifty results at once. This works fine on both sides. 

But one of the pieces of information I wanted was a list of all the Game Genre.  This became problematic as ADO.NET Data Services wanted me to retrieve all 880 games in order to get a list of these Genres (of which there are only 20 some odd). The whole idea of using paging is go avoid the huge overhead of bringing down the whole entity. Interestingly when I executed a LINQ query that used projection into non-entities, the query wasn't supported as projection isn't allowed in the ADO.NET Data Services URI model (which the client uses).

What ADO.NET Data Services does allow is to create Service Operations (e.g. WebGet or WebInvoke) on the Data Service to extend the model for specific cases. There are some limitations (must return IEnumerable<T>, IQueryable<T> or void) but this works pretty well. The difference between returning IEnumerable and IQueryable is whether system queries can be applied to them.  Returning a fixed list (my need) meant to return a IEnumerable<T> list. Intersting that ADO.NET Data Services support returning an IEnumerable<T> of primitive types.  For example my operation was spec'd as:

[WebGet]
public IEnumerable<string> Genres()
{
}

This works and returns a simple XML file with the primitive values.  But alas the Silverlight Data Service Client doesn't support non-entities. I tried using the DataServiceContext.BeginExecute() to call this service and it threw an exception that it couldn't materialize non-entity classes. Hrmph!

This was a case where adding a quick web service call to get this data on the server and return it would have been the easy road, but that's not how I roll, is it?

After confirming this behavior with the Data team, I decided to write an extension to the DataServiceContext class to support this.  In this little piece of code, the same pattern of calling DataServiceContext.BeginXXX is used. To make this work I simply use the HttpWebRequest class to do a simple GET to the server's URI syntax and use LINQ to XML to convert the data into the simple types (String in my case).

I've started to help out with some new ideas on the CodePlex SilverlightContrib project so I thought this was the perfect place for this code.  Its not packaged up yet in a build (and probably won't be until sometime after RTW ships) but if you want to grab it you can grab the latest checkin I made:

SilverlightContrib ChangeSet 41005

I'll be shipping this new demo as soon as RTW ships (its not done yet). Look for the announcement here.

Update on NHibernate 2.0 and LINQ

Silverlight Logo

It seems that because of some internal NHibernate changes that are required to make NHibernate LINQ work really well, the current version of NHibernate LINQ will not be supported.  Evidently there are a number of complex queries that do not work correctly under the current codebase. Its been announced that these changes will be made in the NHibernate 2.1 (which is in development). Follow the link to read the full details!

My Silverlight 2 Data Services Article Code Updated

Silverlight Logo

I've uploaded a new version of my code from my Silverlight 2/Data Services MSDN Article. I took the new Silverlight 2 Data Services client that was released and updated the code example. If you want to get the code, you can download it from my site here:

http://wildermuth.com/downloads/sl2_ds_example.zip

I've also changed and updated the examples (more elaborate versions of the article code) using it on the Silverlight Data site, including both the Entity Framework and the NHibernate examples.  Let me know if find any bugs.

New Build of Silverlight Library for Data Services!

Silverlight Logo

Mike Flasko to the rescue! The ADO.NET Data Services Team has released an interim build of the ADO.NET Data Services Library to address .NET 3.5 SP1 incompatibilities.  While this is just a stop-gap measure, its of great relief that I announce this news as my new MSDN Magazine article was broken because of the incompatibility.

Follow the link for all the information, warnings and download links.  As Mike says, this is an interim build to address the incompatibility but that you shouldn't rely on it for production machines.  The real build will come with Silverlight 2's release whenever that actually happens.

Caveats About My Silverlight 2 Data Services Article

Silverlight Logo

As some of you may have seen, my new article in MSDN Magazine (and online) was recently published. Because we're in a bit of a no-mans-land with builds, the current article only works with .NET 3.5 SP1 Beta and Silverlight 2 Beta 2. This means if you're like most of the world and updated to the full release of .NET 3.5 SP1, some of the code in that article is not going to work for you. I hope to have a new drop of the code (and maybe the article too) once Silverlight 2 ships and is fully compatible with ADO.NET Data Services/Entity Framework that are in the full version of .NET 3.5 SP1.  See my other article talking about the incompatibilities here:

My apologies to anyone who spent too much time trying to get the code in the article working. Such is the problem with beta software and hopefully we'll have a solution sooner rather than later.

My ADO.NET Data Services/Silverlight 2 Article on MSDN Magazine

MSDN Magazine

My new article on creating Silverlight 2 applications that use ADO.NET Data Services is in the new issue of MSDN Magazine. In this article I show you how to create a ADO.NET Data Service as well as how to call that service using the Silverlight 2 Data Service Library. 

What is cool about this approach is that you can issue LINQ queries on the client (in Silverlight 2) that will communicate with Data Services via the REST interface and execute queries and update data on the server.  The substantial difference that you will have to get used to is the use of Asynchronous LINQ queries in Silverlight 2.  Check out the article for all the details.

The Fable of the Perfect ORM

Silverlight Logo

Data is a funny business. While at the moment I am spending a lot of time teaching Silverlight, my passion still lives in the data. I was brought up on  Minisystems (Multi-user CP/M and the like) where you were dealing with something like a database (though we didn't have that as firm a concept as you might think). Later I did quite a lot of desktop database development starting with dBase II (yes, I am that old), Paradox, Clipper, FoxPro and even Access. That naturally led to client-server and N-Tier development. Throughout all the time its become exceptionally clear how much data matters to most applications.

But using databases can be difficult as there is an impedance mismatch with object-oriented development and the natural structure of data. The solution to this for many organizations has been to build data access and business object layers around the data.  These layers were meant to simplify data access for most developers and embed the business logic directly into a re-usable set of code instead of it ending up in the UI layer. This was a good thing...

But the problem is that much of the data access (and to a lesser extent, business object) code was very redundant. Developers ended up writing the same code or simply mimicking schema that was in the database. Some started to develop ways to use the database schema to their advantage to limit the amount of hand-written code was created. While not always called this, this is where object-relational mapping (ORM) products got their start. 

ORM is a good thing.  But ORM is about data access, not business rules. Its a important distinction that needs to be understood.  ORM's typically were bad at defining and managing business rules, but that was never their job. Keep this in mind when you think about ORM and Business Objects (or just read Rocky Lhotka's book on the subject).

Now that ORM's have become a staple of data access, we have a ecosystem where there are a huge number of competing products (1st party, 3rd party and open source). The most common question I get these days when I meet people at user groups or conferences is "What ORM should I use for my new project?" This question is flawed. The problem with this question is that there is not a singular solution for data access (ORM et al.) that solve all problems. In fact there are many solutions to this problem that fit the needs to particular use cases. So when I get this question, I attempt to ask more questions but in reality this isn't a question that can be answered on the back of a napkin.

The recent brouhaha about the Entity Framework is a great example of this problem. Many of the complaints about the Entity Framework (or any ORM really) are central to the viewer's point of view. This is true of NHibernate as well. Its great in the right environment, but lousy in others. I wish I could encourage the community to stop trying to find the perfect ORM.  It doesn't exist. Its like the perfect car, perfect beer or perfect woman. The perfect car for speeding on a racetrack is horrible for taking the kids to hockey practice.

Why do I think this is true? Because I tried to write it. Several years ago I was fed up with the ORM landscape and decided that I would try to write one that fixed the flaws of all the other solutions. I spent nearly four months part time tinkering with the code to get it working the way I wanted it to.  But I kept finding myself backed into corners.  "If I implement it this way, its great for X, but lousy for Y." I finally decided that all ORM's are flawed because the problem is inherently driven by a core set of requirements.  No tool could possibly meet the criteria of every project.

Picking a data access strategy involves more than just functional requirements. Its not about the size of the project, the speed of the runtime environment or even the veracity of the tools. Its bigger than that. Though this list is incomplete, when I talk to people about this problem I encourage them to look at the requirements of their project to include (but not limited to):

  • Functional Requirements
  • System Requirements
  • Skill-set of the Development Team
  • Business Factors
  • Time-to-Market
  • Business Culture
  • Lifetime of Project
  • Volatility of Schema

I could go on, but I think you can fill this out with lots more. The situation is that ORM's that are good for certain environments are bad for others.  For example, if I were writing a website for a mom-n-pop Pizza Parlour in my neighborhood, if I had to have data, I'd likely pick something like "LINQ to SQL" as it is always going to be directly mapped to tables and the size of their database and throughput are low.  Getting the job done on budget is more important than worrying about performance or refactor-ability.

In contrast, if I was building a large financial system where concurrent transactions and high volume processing was critical to the project's success, I'd likely hand-code or use something like NHibernate.  Spending more time on hand coding for performance pays off on a big, high-volume project like this but would be wasted on the other project.

Lastly, if I were to be remotely working on a small project with a team who are not that well versed in database development, I might pick something that did a lot of the code generation for me (like LLBLGenPro) where the developers could get up to speed quickly without having to understand the basics of database development.

Some times its specific philosophies that help find the right match. For example, if persistence ignorance and implicit data loading is important to your team, then a technology like NHibernate makes a lot of sense. But NHibernate often comes with the higher cost of object tracking (e.g. often you'll consume 2x memory with NHibernate since they are keeping the old and new objects to do comparisons).

Other example is the difference in philosophy of data access. One of the driving ideas in Entity Framework is the idea that a developer should never make a request to the database the they don't know about. This is very different from the idea in NHibernate that requesting a related object should *just work*. That's why understanding your team, your culture and your project all come together to help you find the right solution.

Please don't take my mentioning of specific technologies as specific preference but instead understand that picking a tool requires more than trivial review (e.g. (Its included in Visual Studio for free so we should use it.")  Ultimately most projects spend more time tuning and tweaking their data access than building it so picking the right tool that gives you enough control is key to success.  Don't get blinded by shiny designers, its ultimately the code that is more important. 

I welcome your experiences and opinions...