开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜