Rants Tagged with “.NET”

1  2  3  4  5  6  7  8  9  10  11  +  >  >>  (Total Pages: 17/Total Results: 165)

When is a ASP.NET Project Not an MVC Project?

Silverlight Logo

I am working on a hybrid ASP.NET MVC and MVC Dynamic Data project. To work on it I started with the MVC Dynamic Data project assuming this would be a Dynamic Data Project and an MVC project. As Scott Hanselman recently posted, you can mix and match pretty easily so the code was working but I was missing an important piece of functionality in Visual Studio:

My project wasn't being showing these items (or other menu options specific to MVC apps). I suspected it was some magic in the project file so I opened it up in my favorite editor:

<Project ToolsVersion="3.5" 
         DefaultTargets="Build" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">
      Debug
    </Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{F7526D86-12B4-434F-8355-20592CFC4937}</ProjectGuid>
    <ProjectTypeGuids>
      {603c0e0b-db56-11dc-be95-000d561079b0};...
    </ProjectTypeGuids>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Foo.Web</RootNamespace>
    <AssemblyName>Foo.Web</AssemblyName>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
  </PropertyGroup>

The missing bit was a special ProjectTypeGuid: {603c0e0b-db56-11dc-be95-000d561079b0}. You need to add this to the existing ASP.NET project's ProjectTypeGuid list in the project file and magically the project item types appear.

HTH

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!

Atlanta ALT.NET Meetup

ALT.NET

I haven't had a chance yet to drop in on the ALT.NET Meetup but i'll be there this Wednesday. If you're interested in pragmatic development or just want to listen in on some of the ideas surrounding ALT.NET, go RSVP and join us at the meet up.  As a bonus its a "Thinking Man's Tavern" in Decatur which is a cool little cafe with kick ass food.

Will I see you there?

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!

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...

Rigidity in Data Design

Silverlight Logo

To many developers this may seem odd. I talk with many staunch ALT.NET guys, and the DDD philosophy seems to be that data is a top-down or at worse, bottom up design problem. The issue here is that there is an assumption that just simply not true that data design is part of most software development projects. The reality based on my experience as well as the experience of talking with developers in the community is that many projects (though its hard to exactly quantify what percentage) begin with existing data. This is especially true in the enterprise where data exists in many forms from new databases, legacy servers (e.g. mainframes) or even flat files and XML. It is the rare project that is new code against all new data.

For new projects, creating a new database schema that at least in some part mimics the design of a project makes sense. The problem is that over time the data must evolve. I think the reality is that depending on the organization this can be very different. There are some opinions that I think impact the maturation of a data model:

  • "Well if they want access to the data outside the application, I will expose that as a service interface." - I think this is coming from the world of a consultant not a enterprise developer. The reality is that the data maturation happens over time with the help of DBAs, developers and IT people. Its a complicated situation and isolating the database to the non-development stake holders is something that just doesn't happen in the long run.
  • "Transactional schemas are not a good solution for reporting." - While I don't disagree with this idea, it doesn't happen in the real work either. In most large organizations, they have need for data coming out of systems and cannot wait for data warehouses, data marts or reporting servers to be created and maintained.  If they are created as part of the application development, they usually get the short straw of maintenance.  Reporting happens against transactional schemas...period...get over it.
  • "If the application is designed right, the DBA should never need to get involved...we can solve perf problems with caching and smarter data access." - This assumes that the data is isolated from the rest of the organization.  This doesn't happen either. In addition, data changes over time and that's where DBA's can be exceptionally helpful. In my opinion, the form of the data can be improved over time as real data is used in a system. What works for a 1GB database rarely works for a 1 TB database. Lastly, there are often many more readers of data than you might expect. This is related to the reporting story, but also ad hoc attaching of data (damn you Excel and Access) happens. You can't control the gateway to the data as the guys that sign the checks sometimes make dumb decisions that impact the organization...that won't change.

Now I am not suggesting that we need to dumb down designs to deal with the nature of data, but understand that the IT infrastructure of deployed products is a lot more fluid than developers would like. For me it is, "Hope for the best and plan for the worst." This means understand that pushing a design philosophy that can help developers get their job done in a more efficient way as well as create better software is what we all are trying to do, but there are no black and white lines drawn here. No *rule* applies in all situations. I laud the ALT.NET guys for trying to inject better skills and tools into the process, I just rail against the ferocity of zealotry that comes in some of the message. When enterprise developers hear this, they just tune it out instead of taking what helps them and leaving the rest.

That's just my opinion...