This post is a follow-up to an article I wrote a few weeks ago, ADO.NET Entity Framework Comparison Frustration. As a quick re-cap, I was simply trying to filter a list of users with a LINQ query expression by comparing custom classes, not primitive types.

TorvusEntities entities = new TorvusEntities();




// Pull my Account Entity from the database Account matt = entities.Accounts.First(a => a.AccountId == 10); // Attempt to get all Teams by a Team Owner var teams = from t in entities.Teams where t.Owner == matt select t;

However, an exception was thrown.

Unable to create a constant value of type 'Closure type'. Only primitive types (for instance Int32, String and Guid) are supported in this context.

So I left it at that. The Entity Framework could only handle comparison on primitive types, which makes sense of course, since the expression needs to be converted into the underlying data storage language (T-SQL in this case). I was simply hoping that they would provide a more object-oriented way of translating the comparison I hoped to express by some other means. E.g., overriding Object.Equals() or the == operator, implementing a certain interface on my entities, something that felt OO to me.

Today however, I found my answer. Embarrassingly enough, it was in the MSDN docs all along.

A comparison expression checks whether a constant value, property value, or method result is equal, not equal, greater than, or less than another value. If a particular comparison is not valid for LINQ to Entities, an exception will be thrown. [Specifically, the exception I wrote above.] All comparisons, both implicit and explicit, require that all components are comparable in the data store. Comparison expressions are often used in Where clauses for restricting the query results.

And here it is, the confirmation I wanted (albeit not the answer I was hoping for):

LINQ to Entities does not support using a user class as a constant. However, a property reference on a user class is considered a constant, and will be converted to a command tree constant expression and executed on the data store.

Oh, another thing worth mentioning, method returns don't count as so-called constant expressions, and will thrown an exception when attempted.

public class MyBusinessObject
    {
        public int GetId()
        {
            return 5;
        }
    }

    public class Test
    {
        public Test()
        {
            using (TorvusEntities context = new TorvusEntities())
            {
                MyBusinessObject myBo = new MyBusinessObject();
                var accounts = from a in context.Accounts
                               where a.AccountId == myBo.GetId()
                               select a;

                // Exception will be thrown at run-time,
                // methods do not count as Constant expressions
            }
        }
    }
Categories: ADO.NET Entity Framework | C# | LINQ kick it on DotNetKicks.com

February 25, 2008
@ 10:23 PM

Today I just stumbled onto some interesting information regarding placements of script blocks and CSS links. According to some extensive testing performed at Yahoo!, they have published a list of Best Practices for Speeding Up Your Web Site. Many of these rules came as no surprise, for example:

While researching performance at Yahoo!, we discovered that moving stylesheets to the document HEAD makes pages load faster. This is because putting stylesheets in the HEAD allows the page to render progressively.

However, one rule caught my attention:

Rule 5 described how stylesheets near the bottom of the page prohibit progressive rendering, and how moving them to the document HEAD eliminates the problem. Scripts (external JavaScript files) pose a similar problem, but the solution is just the opposite: it's better to move scripts from the top to as low in the page as possible. One reason is to enable progressive rendering, but another is to achieve greater download parallelization.

So sure I thought, maybe it will provide better performance, but when creating internet-facing web sites I am a firm believer in standards and compliance. I admit I don't run my markup through an XHTML validator as much as I should, but I was always under the impression that for valid XHTML, <script> blocks and includes belong in the <head> element. Nay, according to the working W3C XHTML Draft:

The script element places a script within a document. This element may appear any number of times in the head or body of an XHTML document.

Categories: ASP.NET | JavaScript | Web Standards kick it on DotNetKicks.com

February 25, 2008
@ 01:24 AM

Honestly, I'm not sure if this setting is new to Visual Studio 2008 or not, but I just stumbled onto it. Typically when I'm debugging an ASP.NET application I test one page at a time, by right-clicking on the aspx and selecting View in Browser.

image

I prefer this method because I can keep the browser open at all times during development and not have to compile the whole site to quickly test something simple like markup changes. The caveat to this however, is that the Visual Studio debugger is not attached to the cassini process, so I cannot hit any break points I have set. For scenarios when I need to debug and step through code, I press the Debug button, wait for the site to compile and spawn a new browser window, and then I manually navigate to the page I want to debug. Sure this isn't a very big deal, but it would be more convenient to use the browser window I already have open, which is usually already on the page I want to test.

So I found this setting in the Web Application Properties for my site. Now when I enter debug mode, Visual Studio won't spawn a browser, it will simply wait for me to hit Refresh on the browser I already have open. It's a pretty minor change, but I find it to be very convenient.

image

Categories: ASP.NET | Visual Studio kick it on DotNetKicks.com

The ASP.NET MVC framework ships with a number of Visual Studio project and item templates to ease our development tasks. One of these templates is a UserControl built specifically for the MVC framework. We are going to walkthrough building a re-usable Header control that can be added to the top of related pages (in this specific case, this Control will be added to all Account pages). If you want to get technical, I suppose this may be a good candidate for the new Nested Master Page support in Visual Studio 2008. But for our purposes, this will do just fine.

Our end-result will be a control that looks like this, and can be added very easily to our View Pages to provide a consistent navigation element.

image

Create the Control

First let's add a new MVC View User Control control to our Views folder in the solution.

image

image

Once our control is added, we need to make a few very small changes to the CodeBehind file. The MVC framework provides us the flexibility to use a strongly-typed generic version of the ViewUserControl class, much like the ViewPage class. The difference between ViewUserControl and ViewUserControl<T> is that in the generic version you explicitly define the Type of ViewData you will be passing to your UserControl. If you choose to use the non-generic version the ViewData property will be a simple dictionary of objects, instead of strongly-typed properties.

Lets go ahead and tell our UserControl we will be passing it an instance of the AccountViewData class I created. I also added a simple automatic property called SelectedItem that we will use to specify which menu item should be "selected." We will use this property in a future post.

image

image

So here's the markup for our control. You'll notice that was can access the ViewData property the same way we access it from a Page instance.

image

But where does the ViewData come from?

Well, let me first say, I am not an expert on this subject yet. Here is what I know.

  • It Just Works if you have a ViewUserControl<T> and a ViewPage<T> where T is the same type for both!
    • For example, if you have ProfilePage<AccountViewData>, TeamPage<AccountViewData>, FriendsPage<AccountViewData>, your ViewUserControl<AccountViewData> will have its ViewData property automatically populated by the MVC framework! This might not always be ideal however, as it essentially couples your user control to the page(s), as well as gives the control access to ALL data that the page has.
  • An MVC UserControl also exposes a public ViewDataKey property that the page can use to specify a subset of its ViewData that it should forward to the Control. I'll try and elaborate more on this later.
  • The MVCToolkit currently has an overloaded Html.RenderUserControl() method that allows you to specify custom ViewData, as well as assign any properties to the control. This is the method I will be using for the Header control in this walkthrough.

I will possibly post more on this subject once I have more time and experiment with it.

Let's Add the Control to our Page

image

Our first page to use the control will be the Account Profile page. It will be using the generic version of ViewPage, and will be accepting an instance of type AccountProfileViewData, which is defined for your reference above. Something worth noting: I am experimenting with standard inheritance in my ViewData containers. The thought process is simple, AccountViewData will expose the properties that are common to all of my Account-related pages, where the individual Pages themselves will typically have a derived Account__Page__ViewData class to add any additional data. The careful observer may have noticed that my UserControl is accepting the parent type AccountViewData, whereas my Profile page is actually rendering using data from the derived AccountProfileViewData. This will come in handy later.

Method 1 - Drag the UserControl onto the designer surface

This is the method we typically used in WebForms development. Be alert though, Visual Studio will add a <form runat="server"> when you do this. This should be removed, the UserControl will still function.

image

One difference here, as mentioned a moment ago. An MVC UserControl allows us to specify a ViewDataKey. I won't be using this method right now, but I found a good article on the subject here.

image

Take a look at the Controller Action below. We are creating an instance of AccountProfileViewData, which derives from AccountViewData, and passing it to the RenderView method. This makes perfect sense, since our ProfilePage<AccountProfileViewData> expects this! But what about our Header<AccountViewData> control that is expecting AccountViewData? Simply enough, the MVC framework takes care of it for us! Because of standard IS-A OO relationship, our AccountProfileViewData object IS-A AccountViewData object. Our UserControl works just fine with this! Perfect, our User Control only has access to the data it needs, the Page has access to all the data it needs, and everyone is happy.

image

Method 2 - Html.RenderUserControl

image

This is simply another method for adding a UserControl to your page. That null parameter you see in there allows you to pass in any controlData that the control expects. So your page would be responsible for sending it the proper data the control requires. I used null this time because the MVC framework passed my data for me because of the inheritance hierarchy I used. (See above). Also note, you can assign any number of Properties that the UserControl expects using anonymous-type syntax.

I apologize this post was all over the place. If anyone reading this has any questions by all means let me know and I will elaborate further.

Tomorrow I will be writing a follow-up article, where we will convert the control to use a new Html.ActionMenu extension method I wrote. This will allow us a very elegant solution for creating "menu's" of ActionLinks, as well as very cleanly wire-up our SelectedItem property of our Header control.

Categories: .NET | ASP.NET MVC | C# kick it on DotNetKicks.com

Many of us have probably encountered the need for this on various projects. The scenario is simple, we have optional fields that a user may or may not enter values for, and we would like to hide them from display if they were not filled in.

image

The above screenshot could use some cleaning up. Ideally those fields that contain no data should be hidden from the rendered HTML. Our first attempt might look something like below, but hopefully, after 1 or 2 copy pastes any developer will realize this should be handled differently. Who among us has run into maintaining code looking like this?

image

Ok let's go back to the drawing board. The MVCToolkit comes with many extension methods for the HtmlHelper class that ships with the ASP.NET MVC framework. The Html object is accessible to every MVC Page, and will prove invaluable for generating inputs like  RadioButtonLists, DropDownLists, Submit buttons, etc. Let's see how it will look if we add a ConditionalRender extension to the HtmlHelper class. Our ideal code will look something like this:

image

That looks pretty good, but we need a mechanism to tell the ConditionalRender helper how to format the returned HTML. To do this, we can add a string variable to define the format we want returned and pass it to the helper, as shown below:

image

Excellent, as we can see below, the fields the user entered are displayed nicely for us, while the fields that were left empty are not rendered to our output HTML at all.

image

Here is the code the extension method. Just be sure to <add namespace="MattHidinger.Extensions"> to your web.config, so that the extension method will be imported to all of your Pages.

namespace MattHidinger.Extensions
{
    public static class HtmlExtensions
    {
        public static string ConditionalRender(this HtmlHelper helper, object input, string label, string format)
        {
            if (input == null)
                return string.Empty;

            return string.Format(format, label, input.ToString());
        }
    }
}

 

Categories: .NET | ASP.NET MVC | C# kick it on DotNetKicks.com

Today I began playing with the ADO.NET Entity Framework. This framework looks very promising and I plan on experimenting with it heavily this weekend, so expect some more ADOe articles over the next few weeks.

[Update: I discovered more about this subject while reading in-depth the MSDN articles on the ADO.NET Entity Framework. I have updated my conclusions at Entity Framework Comparison Frustration: Explained]

Without going into too much detail, ADOe is very similar to LINQ to SQL. It is essentially a very advanced OR/M that is built into the .NET framework and integrated heavily with Visual Studio designer support, complete with a few snap-in panes for visually mapping your database schema to your CLR objects. I found this post on MSDN explaining the major differences between LINQ to SQL and the ADO.NET Entity Framework.

Later I will go into much more detail about ADOe in general, but for now I wanted to bring up a problem I ran into tonight. My database schema is simple, I have a table called Teams, and a table called Accounts. Each Team has an OwnerId which relates to the AccountId of the Account table -- every Team must have an owner. Lets try and get all Teams for a specific Account...

TorvusEntities entities = new TorvusEntities();
// Pull my Account Entity from the database
Account matt = entities.Accounts.First(a => a.AccountId == 10);

// Attempt to get all Teams by a Team Owner
var teams = from t in entities.Teams
            where t.Owner == matt
            select t;

Looks pretty simple right? The driving force behind ADOe is of course to abstract away data access, so that any .NET developer can read and understand the query intention even if he had never seen T-SQL before in his life. Well, apparently my query isn't acceptable. I am getting an exception:

Unable to create a constant value of type 'Closure type'. Only primitive types (for instance Int32, String and Guid) are supported in this context.

Hmm, ok that's unfortunate. Google is turning up nothing interesting. Apparently the Entity framework can only query primitive types. So naturally I tried to compare the AccountId property instead of a direct instance-to-instance comparison -- something that, IMHO, looks more like T-SQL than C#.

// This works, by comparing the AccountId (int) column
var teams = from t in entities.Teams
             where t.Owner.AccountId == matt.AccountId
             select t;

So I started thinking, maybe ADOe just needs to know how to compare two instances, let's override some operators

public partial class Account
 {
     public static bool operator ==(Account a, Account b)
     {
         return a.AccountId == b.AccountId;
     }
 }

Damn, same exception. Well I'm going to admit that this could very possibly be an error on my part, after all it's 2 AM and I only installed ADOe Beta 3 a few hours ago... I'll update if I discover anything.

Categories: .NET | ADO.NET Entity Framework | ADOe | C# | LINQ kick it on DotNetKicks.com