Sunday, May 30, 2010

Renaming Columns when using Code Only in EF 4.0

The Code-Only feature in Entity Framework 4.0 is currently in CTP 3. Although I’ve been using it a fair bit, one particular pain point for me at  the moment relates to the limited support provided to fine-tune the generated database table columns mapping.

When using Code-Only, one uses a fluent interface to define how your entities (typically POCO classes) should map to a database schema.  For example, you could use the following extract to specify that the Description property in your entity should be mapped in the database as a column with name Description and of type VARCHAR(100) NOT NULL

  1. Property(u => u.Description)
  2.     .IsRequired()
  3.     .IsVariableLength()
  4.     .IsNotUnicode()
  5.     .HasMaxLength(100);

This is cool – I think the above syntax is practical and easy to understand. Even better is that one could generate a complete database schema purely from mapping your domain objects (entity classes). Unfortunately, however, the current CTP 3 release is of very limited (or no) help when it comes to doing the following:

  1. Changing the conventions used by EF when generating the corresponding column names for properties. For example, if you have a Customer entity class with primary key property named Id, then EF will by default always map/generate the property to a column named Id – there’s no way to override this default behaviour to, for example, map to CustomerId instead. Foreign key columns will typically be named xxx_id – though what if you wanted xxxId instead? It would be nice if one could specify a template of column naming conventions – something that would promote the DRY principle.
  2. You can override the column name for your properties, however you must do so for ALL your properties – not merely a subset of them.
  3. There doesn’t seem to be a way to change the ordering of generated columns – worse even, when generating a schema from your domain model, one will often find the primary key column not being the first column in the generated tables. For now, I suspect your best option would be to run a SQL script after schema creation to re-order columns to your liking.

Now obviously I hope that a future Code-Only release would simply provide enhancement to their current fluent interface to address the abovementioned shortcomings; in the mean time, I thought I’d explore some alternatives.

Items 1 and 2 above could be overcome by using the following code block to explicitly specify the column name of each property (here I’m obviously assuming Type Per Hierarchy mapping but that’s not really relevant to the source problem):

  1. MapSingleType(t => new
  2.     {
  3.         CompanyDivisionID = t.Id,
  4.         CompanyDivisionName = t.Name,
  5.         t.Description,
  6.         t.IsActive
  7.     });

Note, by using the anonymous class,

  1. The property Id will be mapped to a column named CompanyDivisionID
  2. If no alternate name is specified, then EF will simply map the name as per default; e.g. the Description and IsActive properties will be mapped to the columns with names Description and IsActive, respectively.

Obviously, having to explicitly mention all your columns (for all your entities) in the mapping so that you can override the default generated column naming convention is tedious at best. I suspect code generation is probably the best interim solution here. Now before you get all excited – I haven’t nearly come up with a complete solution (personally, I think you should rather wait for the next Code-Only release); but at least I can help you get there…or make you learn something in the process…I know I have.

Using LINQ Expressions to Generate Code

For the code generation – you could probably (quite successfully) use T4; however I thought I’d try something that I haven’t had much chance playing around with yet…generating code via LINQ Expressions.

Basically, LINQ introduces a new approach to generate code that is a bit more high level that the IL-based Emit technique. LINQ introduces a runtime representation for expressions which you could think of this as a language-neutral abstract syntax tree that can easily compiled into IL.

Before showing how one could address this problem using Expressions, first realise that the EF provides a different syntax than specified above that is a bit more suited to dynamic code generation:

  1. MapSingleType(t => EntityMap.Row(
  2.     EntityMap.Column(t.Id, "CompanyDivisionID"),
  3.     EntityMap.Column(t.Name, "CompanyDivisionName"),
  4.     EntityMap.Column(t.Description),
  5.     EntityMap.Column(t.IsActive)));

To generate this code dynamically at run time using LINQ Expressions, we need to dynamically build up an expression tree that represents the Lambda function above. The following code snippet shows a simple implementation of how this could be done:

  1. PropertyInfo[] properties = null; //todo: use reflection to get entity's properties...
  2. ParameterExpression tParam = Expression.Parameter(typeof(TEntity), "t");
  3.             
  4. var allEntityMemberExpressions = new List<Expression>();
  5. foreach (var p in properties)
  6. {
  7.     ConstantExpression pName = Expression.Constant(p.Name, typeof(string));
  8.     var member = Expression.Convert(Expression.MakeMemberAccess(tParam, p), typeof (object));
  9.     var entityMemberExpression = Expression.Call(typeof (EntityMap), "Column", null, member, pName);
  10.     allEntityMemberExpressions.Add(entityMemberExpression);
  11. }
  12.  
  13. // convert allEntityMemberExpressions into an array of expressions
  14. // and call EntityMap.Row(EntityMapColumn[])
  15. var entityMapRows = Expression.Call(
  16.     typeof(EntityMap), "Row", null,
  17.     Expression.NewArrayInit(
  18.         typeof(EntityMapColumn),
  19.         allEntityMemberExpressions));
  20.  
  21. MapSingleType(
  22.     // create the lambda: t => EntityMapRow(...)
  23.     Expression.Lambda<Func<TEntity, object>>(
  24.         entityMapRows,
  25.         new ParameterExpression[] { tParam }));
  26.         }
  27.     }

For the most part, hopefully this is self-explanatory – nonetheless, a few explanations:

  1. Line 7: We create a constant expression to represent the column name we want to give our property
  2. Line 8: Expression.MakeMemberAccess with create the expression that represents t.Property. However, some of our properties are likely primitive types (e.g. int) hence we explicitly cast it to type object to avoid a runtime exception in line 9 stating that the static EntityMap.Column(object, string) method couldn’t be resolved.
  3. Line 17: Although we have a collection of expressions – each representing a property/column mapping, we need to convert this to an array of expressions due to the signature of the static EntityMapColumn.Row(Expression[]) method. This is achieved via the Expession.NewArrayInit method.

Anyway, unless you’re a computer, this code is certainly more readable than IL Emit code. This might not necessarily be the best way to address my original problem – but I’ve learned something new today that I’m sure I’m going to find useful in the future…

Thursday, May 20, 2010

PInvokeStackImbalance in .NET 4.0…I beg your pardon?

It’s been quite some time since I’ve played with PInvoke…mmm - could it be as far back as my .NET 1.1 days…back when I just started to appreciate this little thing called “Garbage Collector”…the days where I just started to realise there’s more to life than sacrificing cute and cuddly animals on that big bloody table called C++…selling my soul to Rational (Purify) in the process…yet still somehow convinced that my just completed sacrifice was in vain and instead I just prepared a feast for the Memory Leak devil…
…and just when you get comfortable in the Heaven of managed code…you get smacked right in the face with some old piece of C code…dancing on your now soft delicate body…a body that’s been marinated from the many years of coding in your CLR play pen… and invoking your privates with a stack of imbalance…SAY WHAT???

PInvokeStackImbalance

I came across this today after upgrading a class library that uses PInvoke to .NET 4.0. Specifically, after running the code, I got a PInvokeStackImbalance detection message from the VS2010 Managed Debugging Assistant (MDA). Obviously, my first thought was, as indicated by the message, that the PInvoke signature didn’t match the types of the C function I’m trying to call. However, I still couldn’t see a problem – all the parameter types seemed correct. Also, since I’m running Win 7 64-bit, I figured possibly this could be a 64-bit issue – so I changed the Platform target in my build settings from Any CPU to x86. Still no success.
In the end, the problem seemed to disappear once I’ve changed my build target for the PInvoke class library to target .NET 3.5 (2.0 also works fine) instead. The code worked fine…however this solution just didn’t smell right to me, so I did a bit more digging…and good thing I did!
Turns out that this issue is mentioned in the .NET 4.0 Migration Issues document under the Interoperability section – I’ve copied the relevant section below for quick reference:
Platform invoke To improve performance in interoperability with unmanaged code, incorrect calling conventions in a platform invoke now cause the application to fail. In previous versions, the marshaling layer resolved these errors up the stack. Debugging your applications in Microsoft Visual Studio 2010 will alert you to these errors so you can correct them.
If you have binaries that cannot be updated, you can include the <NetFx40_PInvokeStackResilience> element in your application's configuration file to enable calling errors to be resolved up the stack as in earlier versions. However, this may affect the performance of your application.
Thus, in earlier versions of .NET, we were able to get away with the incorrect calling convention as the .NET framework silently corrected the issue (alas at the cost of introducing a performance penalty).
Armed with this knowledge, it became apparent that the real source of my PInvoke problem was that the PInvoke calling convention for my method defaulted to StdCall – and I needed to use Cdecl instead. Once I updated the code, I was able to restore my class library to target the .NET 4.0 framework.
  1. [DllImport("libfftw3f-3.dll", EntryPoint = "fftwf_plan_r2r_1d", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
  2. public static extern IntPtr r2r_1d(int n, IntPtr input, IntPtr output, fftw_kind kind, fftw_flags flags);
Over the years I might have turned soft from my lack of frequent C++ coding, but at least today I’ll sleep well knowing there’ll be no platform invoking my stack of imbalance…