Archive for March, 2011
NHibernate QueryOver Support For OrderBy Random
by Jim Geurts on Mar.24, 2011, under NHibernate
I had a need to get random records from the database, so I came up with this extension to the NHibernate QueryOver api. It is for Microsoft SQL Server, but it shouldn’t take much effort to port it to other database flavors.
public static class NHibernateExtensions
{
public static IQueryOver<TRoot, TSubType> OrderByRandom<TRoot, TSubType>(this IQueryOver<TRoot, TSubType> query)
{
query.UnderlyingCriteria.AddOrder(new RandomOrder());
return query;
}
}
public class RandomOrder : Order
{
public RandomOrder() : base("", true)
{
}
public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
return new SqlString("newid()");
}
}
HtmlHelper DropDownList for Enumerations
by Jim Geurts on Mar.23, 2011, under Web Development
I’ve really been enjoying the html helpers baked into the ASP.Net MVC framework. To compliment the SelectList extensions that I use, I often use this extension as well. It displays a drop down of enum values for the specified property. It will attempt to get the name via the DisplayAttribute. If the attribute is not present, then it will just get the name from the enum value.
I created an extension method to get the Name of an enum value (as described above):
private static readonly Dictionary<Enum, string> NameCache = new Dictionary<Enum, string>();
public static string GetName(this Enum type)
{
if (NameCache.ContainsKey(type))
return NameCache[type];
var enumType = type.GetType();
var info = enumType.GetField(type.ToString());
if (info == null)
return string.Empty;
var displayAttribute = info.GetCustomAttributes(false).OfType<DisplayAttribute>().FirstOrDefault();
var value = string.Empty;
if (displayAttribute != null)
value = displayAttribute.GetName() ?? string.Empty;
NameCache.Add(type, value);
return value;
}
I then make use of that extension with the enum dropdown helper:
public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
return htmlHelper.DropDownListForEnum(expression, null, null);
}
public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
{
return htmlHelper.DropDownListForEnum(expression, new RouteValueDictionary(htmlAttributes));
}
public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
{
return htmlHelper.DropDownListForEnum(expression, null, htmlAttributes);
}
public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string optionLabel)
{
return htmlHelper.DropDownListForEnum(expression, optionLabel, null);
}
public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string optionLabel, object htmlAttributes)
{
return htmlHelper.DropDownListForEnum(expression, optionLabel, null);
}
public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string optionLabel, IDictionary<string, object> htmlAttributes)
{
if (expression == null)
throw new ArgumentNullException("expression");
var member = expression.Body as MemberExpression;
if (member == null)
throw new ArgumentNullException("expression");
var selectedValue = string.Empty;
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
if (metadata.Model != null)
{
selectedValue = metadata.Model.ToString();
}
var enumType = Nullable.GetUnderlyingType(member.Type) ?? member.Type;
var listItems = new List<SelectListItem>();
foreach (var name in Enum.GetNames(enumType))
{
var type = Enum.Parse(enumType, name) as Enum;
listItems.Add(new SelectListItem
{
Text = type.GetName(),
Value = name,
Selected = name == selectedValue
});
}
return htmlHelper.DropDownListFor(expression, listItems, optionLabel, htmlAttributes);
}
The beauty of this extension method is that it uses the DropDownListFor(…) helper baked into the framework already. So validation, etc is wired up for me. Also worth noting, this extension works with nullable and non-nullable properties. Hope this helps someone save some time…