Another advantage of serving Razor this way(as opposed to ASP.NET MVC's Areas) is you can structure your web pages in the most logical way you wanted them be, you could place Razor pages on any directory and on any level, ServiceStack.Razor won't have a problem serving them.

ASP.NET MVC even with its Areas, feels very constraining. In fact, afaik, the main intent of ASP.NET MVC's Areas is not for stashing related controllers together; Area's main intent is to group the related controller+views(and perhaps plus some controller-specific models) so an application's module could be structured and conceived as one cohesive MVC unit. Perhaps Area's Controllers folder should be named Controller, i.e. in singular form ツ

The ServiceStack solution you've made on Visual Studio can be opened on MonoDevelop, it works out-of-the-box. I tried to open and run the same Visual Studio .sln on MonoDevelop on my main development OS (Mac OS X), It Just Works™

A minor snag, though razor's intellisense is working by following the steps above, I can't figure out how to make the inherits directive be detected properly by Visual Studio. Consequence is, Visual Studio won't be able to give you intellisense for the Model; in fact, Visual Studio will put red squiggly line below the Model property. Things are still working though even Visual Studio put red squiggly line below them

Monday, December 24, 2012

An existing application that become a success and later needed be bolted with multilingual support is where NHibernate adaptability on brownfield projects shines. How well does the application that uses NHibernate can adapt to this change? It handles it seamlessly, in fact there's virtually no changes in your application code needed be made. The localization on both retrieving and saving are being done automatically

Changes needed be made to your domain classes to support multiple languages? Zero, zilch, nada

When we get to the bottom of things, multilingual support is something that should not leak to your domain classes. This is where a capable ORM shines, it insulates your domain classes against infrastructure changes needed be made, everything just works automagically. The infrastructure to support multiple languages might be relational, but the domain classes don't have to reflect the underlying infrastructure. Object-wise, your domain class is still the same cohesive and atomic object your app knows. This is what Object-Relational Mapping is all about. Your object truly mimics the real-world object/entity, not a mere one-to-one mapping of object to relational. The beauty of abstraction

To cut to the chase, these are the infrastructure changes needed be made to enable multilingual support for your app.

Do note that the parameter substitution on SqlInsert and SqlUpdate is order-dependent. If you declare properties in your class in this order: ProductName, ProductDescription; the ProductName will be passed to the first parameter, and the ProductDescription to the second parameter, the last parameter is where NHibernate passes your entities joining key.

You'll notice too that the SqlInsert and SqlUpdate doesn't use filters, this is a limitation of NHibernate filters, filters are applied on functions and conditions only. For that limitation, we'll just set Sql Server's CONTEXT_INFO to desired language upon database connection. For SqlUpdate command, we use Sql Server's merge statement, if the ProductId+LanguageCode is existing on Product_Translation it will update the existing row; if not, then it will insert it.

Sunday, December 23, 2012

As of the time of this writing (and since 2009), NHibernate Linq doesn't support DefaultIfEmpty(), which is a LEFT JOIN functionality. And as such, we won't be able to report entities with collections having count of zero, as that kind of report uses left join.

That doesn't materialize the product orders to List<Order>. That's efficient, it uses COUNT, LEFT JOIN, GROUP BY.

However, the ugly consequence of using IQueryOver (aside from IQueryOver approach is also ugly) is we won't be able to use the more mockable and unit-test-friendly IQueryable. We can use IQueryable even on in-memory objects which makes IQueryable amenable for unit-testing. IQueryOver API looks very convoluted as compared to Linq's API simplicity; to contrast, here's how it looks like if NHibernate's Linq supported DefaultIfEmpty:

It should be noted that no ethically-trained software engineer would ever consent to write a DestroyBaghdad procedure. Basic professional ethics would instead require him to write a DestroyCity procedure, to which Baghdad could be given as a parameter -- Nathaniel Borenstein

The approach above(class EmployeeExcelResult), though it adheres to two of the basic OOP tenets(i.e. inheritance and polymorphism), has a problem if we need to use another kind of list to be exported, say list of product. Aside from that approach is not reusable, it's error prone too. If you are a keen observer, you'll notice that the Age property overwrites the Lastname property, resulting to two exported columns only.

That's flexible now, but we can improve it more. We can make it more flexible by letting us able to specify which columns should be exported to Excel only, and able to specify the column's format. There are three approach we can use when designing an API such as that.

First we maintain a dictionary of column's metadata, where the metadata indicates the column's label and formatting. But dictionary is a non-starter as it promotes stringly-typed programming.

Second is we can use attributes, but that would entail decorating the attributes directly to the concerned class, what if the other party(think B2B's provider) won't allow you to add attributes to their classes? The work-around on this second option is to use buddy classes, this would work only if the consuming party's classes are generated with partials(e.g. WCF) on them. But even buddy classes is an option, buddy classes violates DRY principle, and refactoring wouldn't be available also. Attributes-based API won't let us be creative, even a simple API such as passing the method's address to the function is not possible with attribute, hence necessitates passing the method as string, and calling the method through reflection. Stringly-typed API is brittle and non-discoverable.

That leaves us with the third option, let's design an API that avoids violating DRY principle, and avoids stringly-typed programming to boot. We can use Fluent API and C#'s Expression

The above will appeal to you if you are a Fluent NHibernate fan. If you have used NHibernate 3.2, you might already learned there's another style of mapping by code which is built-in in NHibernate, you can inline-ly(if there's such a word) map your class with the latest NHibernate. Meaning, you don't have to create a separate class for your mapping, this is what "loquacious" (such an unfortunate name, the fluent nomenclature was already taken by others) mapping facilitates. The NHibernate's loquacious API has a more one-stop-shop feel into it. The API below is similar to this style: http://fabiomaulo.blogspot.com/2011/04/nhibernate-32-mapping-by-code.html

If that is even possible, it would be a problem if the similar columns are differently named on the two tables, say PersonID, MencschID (German for PersonID). This can not select all the persons from the American tables:

select * from @tableToSelect where MenschID < 100;

I suggested him this:

WITH x AS
(
SELECT a,b FROM dbo.t
WHERE @tableToSelect = 't'
UNION ALL
SELECT c,d FROM dbo.y
WHERE @tableToSelect = 'y'
)
SELECT * FROM x WHERE a < 100;

A discerning programmer that he is, he quizzed me if that would result to inefficient query. I like that he posed that question and wanted his code to be performant.

If he had asked me that question when I was just a starting developer, I would concur with him. I would naturally assume that it's not efficient to union the tables and filtering it further. I would assume that it would be better if the rows are filtered right from the root source, as illustrated below, and thus enabling both queries of the UNIONed queries to use the available index:

SELECT a,b
FROM t
WHERE @tableToSelect = 't' and a < 100
UNION all
SELECT c,d
FROM y
WHERE @tableToSelect = 'y' AND c < 100;

Fortunately for us, internet is a wonderful place; an eon ago, I stumble upon an article that says RDBMS doesn't short-circuit conditions: http://weblogs.sqlteam.com/mladenp/archive/2008/02/25/How-SQL-Server-short-circuits-WHERE-condition-evaluation.aspx

So this would result to an error (Conversion failed when converting date and/or time from character string):

If we try to fool the RDBMS by eagerly filtering the valid dates first, this would still not work, this will still result to conversion error. A proof that WITH or any form of re-arranging the query doesn't eagerly execute the query.

That means, the conditions' execution order is not executed based on how you arrange your query. The outer query's conditions could be mixed with the inner query's condition by your RDBMS. Armed with that knowledge in mind, the following two queries are executed similarly:

SELECT *
FROM t
WHERE @tableToSelect = 't' and a < 100
UNION all
SELECT *
FROM y
WHERE @tableToSelect = 'y' AND c < 100;
WITH x AS
(
SELECT a,b FROM dbo.t
WHERE @tableToSelect = 't'
UNION ALL
SELECT c,d FROM dbo.y
WHERE @tableToSelect = 'y'
)
SELECT * FROM x WHERE a < 100;

That is, the second query(CTE) is expanded to the same query as the first query; thus, the second query's a < 100 expression utilizes all the available indexes on both tables, making the query performant. Given that they are semantically the same, it's better to use the second query as it's easier to maintain, the query's condition is just placed on one location only, there's no code duplication involved. Some shun the table-deriving or CTE approach, as they think enclosing the query on CTE or table-deriving it would deprive the expression a < 100 the SARGability it needed; this is not true, CTE-using queries can still use the available indexes on both tables.

If you are a keen observer, you'll ask, what will happen to the query with the date detection in it? How to prevent the query from executing the conversion if the field is not a date? We can really do short-circuit in SQL Server explicitly, but that would entails using CASE WHEN, and that would make your query not being SARGable. Here's the short-circuited query:

SELECT *
FROM t1
WHERE CASE WHEN ISDATE(val) = 1 AND CONVERT(DATETIME, val) < GETDATE() THEN 1 END = 1

Another approach, is to use an optimization fence on ISDATE. This way, SQL Server don't need to merge the ISDATE condition with CONVERT, avoiding the conversion failed error.

When was the last time you have a nerdgasm? Was it since you last saw Iron Man's trailer where you've seen his suitcase armor expanded to an Iron Man suit and automatically costumed(armed?) him? Was it since you first learned Linq/lambda and all the expressiveness, succinctness and slickness you can accomplish with it?

Wow, that was so 3 years ago! In internet time it's an eternity! It's time to rectify that long drought. There are times we are in a Zen-like state (a.k.a. in the zone), wherein the code to implement something are all on your head already, your project is virtually done, ready to be coded/typed; and the only thing that is a bottleneck to implement the app is the interface between you and the computer, is the keyboard, is the typing.

With ZenCoding, typing humongous HTMLs off the top of your head will be a thing of the past. Given the following tags..