【问题标题】:Custom Linq Query where property name is unknown at compile time编译时属性名称未知的自定义 Linq 查询
【发布时间】:2009-11-25 23:31:39
【问题描述】:

当我尝试以下操作时,我得到一个错误:不能在没有投影的条件上使用子查询。

谁能告诉我如何将属性名称添加到 IQueryable:repository.Query(类型在类级别定义)。

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

                    }
                }

            }

好的,在一些帮助下,我找到了解决方案,并发现了原始代码中的错误。由于这是一个 NHibernate 存储库,因此以下代码可以正常工作:

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

                }
            }

        }

【问题讨论】:

  • 不确定您的错误,但“值”可能包含存储在所述属性中的值,而 .GetProperty(string) 应该返回一个 PropertyInfo。据我所知,您的 where 子句将始终返回一个空集。

标签: c# linq


【解决方案1】:

您可能想为此尝试Dynamic LINQ。动态 LINQ 代码作为 VS2008 Code Samples 的一部分提供。

 using System.Linq.Dynamic;

 ...

 var count = repository.Query<T>()
                       .Where( "@0 == @1", property.Name, value )
                       .Count();

【讨论】:

  • 好主意,我真的认为这会解决我的问题,但现在我得到一个空引用异常被抛出:[NullReferenceException: Object reference not set to an instance of an object.] NHibernate.Criterion.SubqueryExpression ..ctor(String op, String quantifier, DetachedCriteria dc)
  • 我不知道动态 LINQ 代码是否可以以任何形式与 nHibernate 一起使用,尽管我怀疑有些事情可能会起作用。我知道此时 LINQ-to-nHibernate 的功能并不完整。您可能希望将 nHibernate 信息添加到您的问题并重新提问。也许有一种方法可以直接在 nHibernate 中执行此操作。
  • 可以,但是感谢您的回答,因为您的解决方案是正确的,所以无论如何都会接受。
  • @Richard 你有没有发现空引用异常?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 2016-05-18
相关资源
最近更新 更多