score:0

How about this one:

User user = _session.QueryOver<User>().Where(x => x.securedusername == _encryptionProvider("Hamza")).SingleOrDefault();

Edited: Your query has issues as i have mentioned in the comment above. One option is, (This can be done only if the usernames are unique, otherwise there can be clash) 1. you have to come up with a index which is unique to each string value. for EX:

SAM = xyz(110111101)
SAMI = xyzk(110111101001)

this index has to be inserted for each customer in the database.

then you can go for like:

`User user = _session.QueryOver<User>().Where(x => x.Index.Contains(IndexGenerator("Hamza"))).SingleOrDefault();//I do not know weather this Contains method exist in nhibernate`. But there should be. so find that :)

But this query will give some unnecessary values as well, But that can be further filtered using the actual username after decryption in the coding. That can get the precise search results.

You can use this IndexGenerator as your _encryptionProvider if it is cryptic.

score:0

I have never used NHibernate, but the problem is that the definition of Username is in the model and not in the database.

Basicly you have two choices (bear in mind that I've never actually used NHibernate but other entity frameworks/ORMs), and possibly a third depending on NHibernate's implementation of IQueryable.

Load the entire table into memory (if it is small and you do this query often that might be useful, because I guess NHibernate has some smart caching?):

User user = _session.QueryOver<User>().ToList().FirstOrDefault(x => x.Username == "Hamza");

The second is checking against the encrypted string, as provided by @Diode:

// Resolve string, since we are using LINQ2SQSL in some form
var encName = _encryptionProvider.Encrypt("Hamza"); 
User user = _session.QueryOver<User>().FirstOrDefault(x => x.SecuredUsername == encName);

If you can use a specific instance of IQueryable for wrapping purposes, that would be one solution. Have a look at http://msdn.microsoft.com/en-us/library/bb351562.aspx for a description of IQueryable.

But basicly, the encryption has to happen on the server, ie not in the database, and that kinda limits your options.

EDIT: Search for all users matching "Hamz*", we have to load to memory and check there:

var users = _session.QueryOver<User>().ToList().Where(x => x.Username.StartsWith("Hamz"));

score:1

You can use a custom type to encrypt your Username (instead of doing the encryption in the User class, do the encryption in the custom type) see http://nhforge.org/blogs/nhibernate/archive/2009/02/22/encrypting-password-or-other-strings-in-nhibernate.aspx

When you query, you will only be able to query for exact matches, but you will be able to do a query like:

User user = _session.QueryOver<User>()
    .Where(x => x.Username == "Hamza")
    .SingleOrDefault();

If you want to match case-insensitively, you can convert the value to upper/lowercase in the custom type.

If you want to do LIKE searches, then you will need to look at some other type of indexing - eg. Lucene.NET and NHibernate.Search


Related Articles