2013-02-14 26 views
1

我正在開發一個Caliburn.Micro的Silverlight 5應用程序(對於那些不熟悉Caliburn的人不用擔心,您無需理解Caliburn的東西來回答我的問題)作爲MVVM框架,我需要從SQL表中讀取一些數據。我選擇了WCF數據服務(理由不在這一點)。在Silverlight中添加/更改DataServiceQuery <T>

爲了使事情具有普遍性和可重用性,我創建了一個視圖模型,該視圖模型需要服務的DataServiceQuery<TEntity>URI並加載數據。我還爲這個視圖模型創建了一個視圖,使用telerik RadGridView來顯示數據,Caliburn IResult在子窗口中顯示視圖模型。我想要使​​用這個視圖模型和視圖,因爲在我的應用程序中,我需要從表中選擇一些東西,我有許多窗體,其中用戶需要從大型列表(SQL表)中選擇一些字段。

public class SelectDBEntitiesViewModel<TEntity, TContext> : DialogScreenBase, IAmClean 
     where TEntity : class, new() 
     where TContext : DataServiceContext 
    { 
     public SelectDBEntitiesViewModel() 
     { 
     } 

     public void Load() 
     { 
      // load 
     } 

     public DataServiceQuery<TEntity> Query{ get; set; } 

     public void Filter() 
     { 

      Query = _originalQuery.AddQueryOption("$filter", "startswith(" + _filterProperty + ",'" + FilterValue + "')"); 
      Load(); 
     } 
    } 

所以從一個協程其他一些視圖模型我創建這個IResult類是這樣的:

public IEnumerable<IResult> SelectInternalBeneficiary() 
    { 
     SelectDBEntitiesResult<InternalBeneficiary, QMSEntities> r = new SelectDBEntitiesResult<InternalBeneficiary, QMSEntities>(_oDataUri); 
     r.Query = (from ib in r.DataContext.InternalBeneficiaries where (ib.Firma == Model.GroupCompany) select ib) as DataServiceQuery<InternalBeneficiary>;   r.PageSize = 2; 
     r.ColumnSettingsName = UserSettings.SEL_INTERNALBENEFICIARIES_GRID; 
     r.Header = "SELECT AN INTERNAL BENEFICIARY"; 
     r.Subtitle = "List of all departments"; 
     yield return r; 
     Model.InternalBeneficiary = r.SelectedObject.DenumireDepartament; 
    } 

所以,當這個方法運行有一個子窗口打開,視圖模型加載數據和視圖中的網格被加載。

現在一切正常,但在視圖中我有一個文本框在右上角,我想用來通過向查詢添加一些新的子句來過濾數據。這個我需要在我的一般SelectDBEntitiesViewModel裏面做,但問題是這個視圖模型使用的查詢是從外部作爲參數接收的。我曾嘗試在篩選方法如下:

Query = _originalQuery.AddQueryOption("$filter", "startswith(" + _filterProperty + ",'" + FilterValue + "')"); 

但是當我運行該應用程序我得到,當然這個錯誤:

Can't add query option '$filter' because it would conflict with the query options from the translated Linq expression. 

我明白是怎麼回事(我已經有一個where子句在查詢中,不能添加另一個過濾器),但我不知道如何解決它。

任何想法?

回答

0

沒關係,我設法找到了如何創建Expressions並將它們添加到Query

此方法添加一個啓動型過濾到IQueryable<T>

private IQueryable<T> StartsWithQuery<T>(IQueryable<T> query, string propertyValue, PropertyInfo propertyInfo) 
     { 
      ParameterExpression e = System.Linq.Expressions.Expression.Parameter(typeof(T), "e"); 
      MemberExpression m = System.Linq.Expressions.Expression.MakeMemberAccess(e, propertyInfo); 
      ConstantExpression c = System.Linq.Expressions.Expression.Constant(propertyValue, typeof(string)); 
      MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }); 
      System.Linq.Expressions.Expression call = System.Linq.Expressions.Expression.Call(m, mi, c); 
      Expression<Func<T, bool>> lambda = System.Linq.Expressions.Expression.Lambda<Func<T, bool>>(call, e); 
      return query.Where(lambda); 
    } 

這種方法增加了一個等於過濾類型爲IQueryable<T>

private IQueryable<T> EqualsQuery<T>(IQueryable<T> query, string propertyValue, PropertyInfo propertyInfo) 
     { 
      Expression<Func<T, bool>> additionalExpression = 
       System.Linq.Expressions.Expression.Lambda<Func<T, bool>>(
        System.Linq.Expressions.Expression.Equal(
         System.Linq.Expressions.Expression.MakeMemberAccess(
          System.Linq.Expressions.Expression.Parameter(typeof(TEntity), "te"), 
          typeof(TEntity).GetProperty(_filterProperty)), 

       System.Linq.Expressions.Expression.Constant(FilterValue)), 
        System.Linq.Expressions.Expression.Parameter(typeof(TEntity), "te")); 

      return query.Where(additionalExpression); 
     } 

表達式樹是pr強大的

相關問題