Custom Linq Query where property name is unknown at compile time
When I try the following I get an error : Cannot use subqueries on a criteria without a projection.
Can anyone tell me how I would create the added expression with the property name to the IQueryable: repository.Query (the type is defined at the class level).
private void CheckConstraints(T model, ModelStateDictionary modelState)
{
foreach (var property in typeof(T).GetProperties())
{
开发者_StackOverflow中文版 if (property.HasCustomAttribute<UniqueInDatabase>())
{
object value = property.GetValue(model, null);
var count =
repository.Query<T>().Where(x => x.GetType().GetProperty(property.Name) == value).Count();
if ((model.Id > -1 && count > 1) || (model.Id == -1 && count > 0))
modelState.AddModelError("Not unique", string.Format("{0} already exists in database", property.Name.CapitalizeSpace()));
}
}
}
OK so with some help I have found a solution as well as spotting an error in the original code. As this was an NHibernate repository the following code works fine:
private void CheckConstraints(T model, ModelStateDictionary modelState)
{
foreach (var property in typeof(T).GetProperties())
{
if (property.HasCustomAttribute<UniqueInDatabase>())
{
object value = property.GetValue(model, null);
var count = repository.GetSession().CreateCriteria<T>()
.Add(Expression.Eq(property.Name, value))
.Add(Expression.Not(Expression.Eq("Id", model.Id)))
.List().Count;
if (count > 0)
modelState.AddModelError("Not unique", string.Format("{0} already exists in database", property.Name.CapitalizeSpace()));
}
}
}
You might want to try Dynamic LINQ for this. The Dynamic LINQ code is available as part of the VS2008 Code Samples.
using System.Linq.Dynamic;
...
var count = repository.Query<T>()
.Where( "@0 == @1", property.Name, value )
.Count();
精彩评论