tags:

views:

209

answers:

1

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())
                {
                    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()));

                }
            }

        }
+1  A: 

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();
tvanfosson
Good thinking, I really thought this would solve my problem but now I get a null refernce exception being thrown: [NullReferenceException: Object reference not set to an instance of an object.] NHibernate.Criterion.SubqueryExpression..ctor(String op, String quantifier, DetachedCriteria dc)
Richard
I have no idea if the Dynamic LINQ code works with nHibernate in any form, though I suspect that some things might work. I know that LINQ-to-nHibernate is not fully featured at this point in time. You might want to add the nHibernate information to your question and re-ask. Perhaps there's a way to do this in nHibernate directly.
tvanfosson
OK will do, but thanks for the answer will accept anyway as your solution was correct.
Richard