1

私はCaliburn.Microを使用してSilverlight 5アプリケーションを開発しています(Caliburnに慣れていない人は心配しないでください、私の質問に答えるためにCaliburnのものを理解する必要はありません)、MVVMフレームワークからいくつかのデータを読み取る必要がありますSQL テーブル。私は WCF Data Service を選択しました (理由は重要ではありません)。

物事を一般的で再利用可能にするために、サービスの と を取り、データをロードするビュー モデルを作成しまし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が、問題は、このビュー モデルが使用しているクエリがパラメーターとして外部から受信されることです。Filter メソッドで次のことを試しました。

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 句があり、別のフィルターを追加することはできません) が、それを回避する方法がわかりません。

何か案は ?

4

1 に答える 1

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

このメソッドは、equals to タイプのフィルタリングを に追加します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);
        }

式ツリーは非常に強力です

于 2013-02-15T10:29:11.813 に答える