在Silverlight中添加/更改DataServiceQuery <t> </t>

时间:2013-02-14 13:17:11

标签: linq wcf-data-services silverlight-5.0 caliburn.micro

我正在开发一个带有Caliburn.Micro的Silverlight 5应用程序(对于那些不熟悉Caliburn的人不要担心,你不需要了解Caliburn的东西才能回答我的问题)作为MVVM框架,我需要阅读SQL表中的一些数据。我选择了WCF数据服务(原因不在此处)。

为了使事情变得通用和可重用,我创建了一个视图模型,它接受服务的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子句,无法添加其他过滤器)但我不知道如何解决它。

有什么想法吗?

1 个答案:

答案 0 :(得分: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);
        }

表达式树非常强大