2009-11-25 75 views
1

当我尝试以下时出现错误:无法在没有投影的条件下使用子查询。自定义Linq查询,其中属性名称在编译时未知

任何人都可以告诉我如何创建带有属性名称的添加表达式到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())); 

       } 
      } 

     } 
+0

不知道你的错误,但“价值”可能包含存储在上述财产而.GetProperty(串)应该返回你的PropertyInfo值。从我看到的,你的where子句总是会返回一个空集。 – flq 2009-11-25 13:25:41

回答

2

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

using System.Linq.Dynamic; 

... 

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

好的想法,我真的认为这会解决我的问题,但现在我得到一个null引用异常被抛出:[NullReferenceException:对象引用未设置为对象的实例。] NHibernate.Criterion.SubqueryExpression..ctor(String op ,字符串量化器,DetachedCriteria dc) – Richard 2009-11-25 14:37:02

+0

我不知道动态LINQ代码是否以任何形式与nHibernate协同工作,尽管我怀疑有些东西可能会起作用。我知道LINQ-to-nHibernate在这个时候还没有完全的功能。您可能需要将nHibernate信息添加到您的问题并重新提问。也许有一种方法可以直接在nHibernate中执行此操作。 – tvanfosson 2009-11-25 14:48:15

+0

确定会做,但谢谢你的答案将接受无论如何,因为你的解决方案是正确的。 – Richard 2009-11-25 14:49:43