NHibernate QueryOver is not a Linq provider (that is how to do join with QueryOver API)

Starting from NHibernate 3.0 a new API was build as a wrapper around the ICriteria object.

Obviously I’m talking about the powerful API called QueryOver. With this API you can build a wide range of query object, from the simplest to the more complicated one. But you need to remember that this API is not a Linq provider, and then you cannot apply those constructs typically applied in a Linq query. I explain with an example what I really mean.

Introduction: you have a data model with 2 table, Category and Customer, with a one-to-many relationship between them.

With Entity Framework and Linq To Entities it’s pretty simple to query data that belong to both entities, thanks to navigation properties and Linq provider, i.e. all customers that belong to a category with a specified Id, as shown in this example:


var customerList = customers.Where(c => c.CategoryId == 1);

If you try to execute the same query with the same where conditions applied to a QueryOverObject, like this example:


QueryOver<Customer>; qu = QueryOver.Of<Customer>()
      .Where(c => c.CategoryId == 1);

This code throws a NHibernateException saying that “could not resolve property: Category.Id of : MyNamespace.Customer”, suggesting to verify the mapping as property “Category.Id” could not be found”.

Obviously such a property doesn’t exist at all, it’s only the QueryOver API that concatenates the Navigation property and and its field named Id (in this example).

This means that: you cannot make a query with QueryOver API that refers to fields belonging to a navigation property in where clause….without explicitly defying a join between the object itself and its navigation property. An example will help to understand better.

Category cat = null;
QueryOver<Customer> query = QueryOver.Of<Customer>()
 .JoinAlias(x => x.Category, () =>; cat)
 .Where(x => cat.Id == 1);

I have defined a join with the JoinAlias method, which uses an alias (the Category object declared two rows before) to project the object under the navigation property. After that you can use this alias inside the others method (such as “Where” in this example) to refer to the navigation property field (cat.Id).

As you can see, the way you write the lambda expression inside a Linq provider’s where clause is quite different than the “”Where” condition of a QueryObject object.

Not even the logical operator “And” can be used in the same way. To apply this logical operator to the “where” filter you have to use the “And” method, as shown here:

Category cat = null;
QueryOver<Customer> query = QueryOver.Of<Customer>()
   .JoinAlias(x => x.Category, () => cat)
   .Where(x => cat.Id == 1)
   .And(x => cat.IsEnabled);

Pluralisation services in .Net Framework

Starting from .Net Framework version 4.0 developers have available a new service for converting a single word from singular to plural form, or from plural to singular form.

I’m talking about the class PluralizationService contained in namespace System.Data.Entity.Design.PluralizationServices in assembly System.Data.Entity.Design.

it’s very simple to use it:

string plural = System.Data.Entity.Design.PluralizationServices
        .PluralizationService.CreateService(new System.Globalization.CultureInfo("en-US"))
        .Pluralize(singular);
// returns "dresses";

or

string singular = "woman";
string plural = System.Data.Entity.Design.PluralizationServices
         .PluralizationService.CreateService(new System.Globalization.CultureInfo("en-US"))
         .Pluralize(singular);
// returns "women";

I don’t know how reliable a translation service inside a framework can be, but it’s use can be very useful.

Be careful because the only supported culture is “English” (so far). Then if you call the service with another culture, i.e. Italian (it-IT), you end up with a NotImplementedException, as shown here:

Technorati Tags: ,

Dynamic build of generics types at runtime

How to create dynamically a type in .Net when it’s only known a string representation of that type, I think it’s an operation known to almost all .Net programmers, but what happened with types with type parameters (or generics) ?

In .Net is possible to create dynamically both generics with a known type, i.e. List<>, and generics with type in turn dynamically built.

Here’s an example:

a) Dynamic generated both type parameter and type

Type collectionType = Type.GetType("System.Collections.Generic.List`1, mscorlib");
if (collectionType == "null")
    throw new InvalidOperationException("Invalid type");
Type genericType = Type.GetType("MyNamespace.MyType, MyAssembly");
Type listWithGeneric = collectionType.MakeGenericType(genericType);
var myList = Activator.CreateInstance(listWithGeneric) as IList;

b) Dynamic generated type parameter with a known type (System.Collection.Generic.List in this case):

Type genericType = Type.GetType("MyNamespace.MyType, MyAssembly");
Type listWithGeneric = typeof(List<>).MakeGenericType(genericType);
var myList = Activator.CreateInstance(listWithGeneric) as IList;
Technorati Tags: ,,

WCF 4.0 and its defaults

The default endpoint and default binding provided by WCF 4.0 are obviously great features that can save developing and testing time, but sometimes this conventional configuration don’t help in case you have some trouble with certain setting that doesn’t work.

The setting I mean in this case concern the Windows Authentication over HTTP.

To enable this setting you have only to configure the basic http bindings with a specified security mode, and then, obviously, configure the IIS authentication for the site/virtual directory that host your service to enable Windows Authentication and disable Anonymous access.

If you make this two simple change, you end up with an ASP .Net error page which says this:

“Security settings for this service require Anonymous Authentication, but it is not enabled for the IIS application that hosts this service”,

that is to say that the Windows Authentication isn’t working and the service requires Anonymous Authentication that is not enabled and then here’s the error.

Why although the configuration is it not working? Because you have not specified a binding for your service, and then the default binding comes into play, and the default binding requires Anonymous Authentication, which is not enabled.

The next logical step is to provide a specific binding configuration,  which maps the binding named “BasicHttpEndpointBinding” defined early with your service.

But when you run the service the error is always the same. What’s wrong with this configuration ?

The problem here is the service name you provided. This name must match with the service name written inside the .svc file of your service. If this name doesn’t match, the explicit binding configuration doesn’t match with those provides by your service as well, and then you fall into the default binding behavior again.

Otherwise, if the service name matches everything works fine.

Moral of the story: “Pay always attention to the default values of any configuration”!

AddessAccessDeniedException in WCF 4.0

If you host a WCF service on a machine with UAC enabled, Vista or Win7 for example, you might run into a seemingly strange exception:

The reason is due to the fact that to host a WCF service you need to register its url, and this task requires administrator privileges, and this means as well that if you run Visual Studio as Administrator everything works fine, but what if you don’t have this possibility ? Or how to register an URL for it to work ?

If you follow the link mentioned in the error message you waste your time because the resulting link is too general for this specific error. I used this approach: I downloaded HttpNamespaceManager, a little and nice open source utility (not an official Microsoft tool), also provided with source code, that just does this, register an URL even assigning permissions to users.

After the URL registration your service will work fine.

Default endpoints in WCF 4.0

Starting from WCF 4.0 it’s possible to use a default endpoint in absence of explicit configuration. This means that you can avoid to configure an explicit endpont because of a default mapping between protocol schema and bindings described in the configuration file machine.config.

Here is the default content of that mapping:

For example, in the case of presence of “http” in the protocol, it will be used the default binding “basicHttpBinding” without the need to configure an endpoint explicitly.

Now, to test this new feature all you need is to create a simple service without an explicit endpoints configuration and then read hits configuration such as the following example:

This code in .Net Framework 4.0 will work fine, while .Net 3.5 would have required the endpoint configuration

Link utili della settimana #12

Microsoft – Domain Oriented N-Layered .NET 4.0 App Sample
Per gli amanti (come me) di DDD, ecco un progetto molto interessante riguardante un “DDD N-Layered Architecture Style”, ovvero una applicazione di esempio che mostra uno scenario di business molto semplice che include alcune implementazioni di DDD Design patterns (Repository, UoW, Entity, Aggregate, Value-Object, etc), facendo uso di .Net 4.0, EF 4.0, WCF 4.0, differenti client partendo da WPF e Silverlight.

NHibernate Query Analyzer, open source project, il cui nome dice già tutto

Patch for VS 2010 Find and Replace Dialog Growing
Bello questo piccolo bug di Visual Studio 2010 . Ogni volta che si usa la finestra di dialogo Find and Replace, la stessa “cresce” di dimensioni (16px) rispetto alle dimensioni precedenti (quindi, all’infinito).  Nel link è presente la patch per sistemarlo.

Generate Data
Ogni giorno si scoprono siti web davvero inusuali. Questo sito offre il servizio gratuito di generazione di dati casuali utilissimi per il test delle proprie applicazioni. E’ possibile scegliere un range di dati possibili (id autoincrementanti, dati di testo come nomi, città, nazioni, valori float o booleani, ecc.), e generare dei dati casuali con un click di mouse.

Metodo String.IsNullOrWhiteSpace, era ora!

Metodo String.IsNullOrWhiteSpace

non capisco come si sia dovuto attendere la versione 4 della BLC per introdurre un metodo la cui funzionalità è sicuramente utilizzatissima dagli svluppatori, costringendo questi ultimi a scrivere helper class oppure, ma solo a partire dal Framework 3.5, extention methods ad hoc.

Infatti, prima dell’introduzione di questo metodo, a meno ripeto di non scriversi un metodo ad hoc. erano necessari ben 2 passaggi per determinare se una stringa fosse uguale a null oppure vuota,  includendo nel concetto di vuota anche lo spazio poichè esso è a tutti gli effetti un carattere.

Vale a dire che questo codice:

ritorna False perchè nel concetto di Empty non è incluso lo spazio.

Si potrebbe sottoporre preventivamente a Trim la stringa da valutare, ma sfortunatamente nel caso in cui la stringa sia null l’invocazione del metodo Trim() solleva una eccezione “Object not set to an instance of a object”.

Come detto, erano necessari 2 passaggi per determinare se una stringa non è null e non è neanche vuota, spazi compresi, ovvero qualcosa del genere:

Fortunatamente con il .Net Framework 4 ce la caviamo con una sola riga di codice:

CLR – Forwarding type

Il CLR consente di spostare il codice di una classe da un assembly ad un altro senza  dover ricompilare il codice client che usa la classe in questione.

Questa caratteristica è nota come Type Forwarding.

Supponendo di avere la classe Class1 nell’assembly Ass1, se per questioni di refactory del codice sorgente la classe viene spostata nell’assembly Ass2, sembrerebbe a prima vista necessario ricompilare anche il codice che referenzia l’assembly Ass1 per aggiungere una reference all’assembly Ass2 e modificare la dichiarazione della classe Class1.

Tutto ciò non è necessario. Basta decorare l’assembly Ass1 (la nuova versione, quella priva della classe Class1) con l’attributo TypeForwardedToAttribute, in questo modo:

[assembly:TypeForwardedToAttribute(typeof(Class1))]

Così facendo, il codice client può continuare a referenziare l’assembly Ass1, e quindi non è necessaria una sua ricompilazione. Ogni richiesta che l’assembly riceverà per quella classe verrà reindirizzata al nuovo assembly che conterrà la classe stessa.

Ma tutto ciò ha una controindicazione a mio avviso non indifferente: l’assembly Ass1 che conteneva la classe che ora non contiene più dovrà per forza di cose referenziare l’assembly Ass2 che ora contiene il tipo.

Inoltre, e qui sarei curiosissimo di conoscere la motivazione, questo attributo non è utilizzabile in Visual Basic 2005 (e quindi con il .Net Framework 2.0). Infatti Visual Basic 2005 può solo “consumare un forwarded type” scritto in un altro linguaggio.