Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Linq表达式转换为QueryExpression或FetchXML_Linq_Dynamics Crm_Fetchxml - Fatal编程技术网

将Linq表达式转换为QueryExpression或FetchXML

将Linq表达式转换为QueryExpression或FetchXML,linq,dynamics-crm,fetchxml,Linq,Dynamics Crm,Fetchxml,我的最终目标是将linq表达式转换为获取xml。我打算在MS CRM 2011中为自定义网格使用fetch XML 从本文中,我可以将QueryExpression转换为FetchXML 但我不知道如何将Linq表达式转换为QueryExpression。当我说linq表达式时,我指的是IQueryable类型的对象 有没有人有过这样的经验或者知道怎么做 Cheers在LINQ表达式上调用ToString()应该返回FetchXML在LINQ表达式上调用ToString()应该返回FetchXM

我的最终目标是将linq表达式转换为获取xml。我打算在MS CRM 2011中为自定义网格使用fetch XML

从本文中,我可以将QueryExpression转换为FetchXML

但我不知道如何将Linq表达式转换为QueryExpression。当我说linq表达式时,我指的是IQueryable类型的对象

有没有人有过这样的经验或者知道怎么做


Cheers

在LINQ表达式上调用ToString()应该返回FetchXML

在LINQ表达式上调用ToString()应该返回FetchXML

您可以使用反射从
IQuerable
获取提供程序并调用其上的Translate方法来获取
QueryExpression

下面是我正在使用的扩展方法:

public static QueryExpression ToQueryExpression(this IQueryable @this)
{
    var provider = @this.Provider;
    var translateMethod = provider.GetType().GetMethod("Translate");
    var query = (QueryExpression)translateMethod.Invoke(provider, new object[] { @this.Expression });

    return query;
}
如果您在C#中使用某种类型的动态包装器进行反射,您可以这样做:

public static QueryExpression ToQueryExpression(this IQueryable @this)
{
    dynamic provider = ExposedObject.From(@this.Provider);

    return provider.Translate(@this.Expression);
}

至于fetch,您需要使用
QueryExpression
,然后发出一个请求
QueryExpressionToFetchXmlRequest
,该请求返回
QueryExpressionToFetchXmlResponse
响应,该响应具有属性
FetchXml

,您可以使用反射来获取
QueryExpression
,从
IQuerable
获取提供者并调用其上的Translate方法

下面是我正在使用的扩展方法:

public static QueryExpression ToQueryExpression(this IQueryable @this)
{
    var provider = @this.Provider;
    var translateMethod = provider.GetType().GetMethod("Translate");
    var query = (QueryExpression)translateMethod.Invoke(provider, new object[] { @this.Expression });

    return query;
}
如果您在C#中使用某种类型的动态包装器进行反射,您可以这样做:

public static QueryExpression ToQueryExpression(this IQueryable @this)
{
    dynamic provider = ExposedObject.From(@this.Provider);

    return provider.Translate(@this.Expression);
}

至于fetch,您需要使用
QueryExpression
,然后发出一个请求
QueryExpressionToFetchXmlRequest
,该请求返回
QueryExpressionToFetchXmlResponse
响应,该响应具有属性
FetchXml

,所提供的解决方案不适用于Chielus提到的CRM2013 SDK程序集

对于CRM2013,您可以使用以下扩展方法:

public static class QueryProviderExtensions
{
    public static QueryExpression ToQueryExpression<T>(this IQueryable<T> items)
    {
        var queryProvider = items.Provider;

        var queryProviderType = queryProvider.GetType();
        var listType = typeof(List<>);

        var projectionType = queryProviderType.Assembly.GetType("Microsoft.Xrm.Sdk.Linq.QueryProvider+Projection");
        var navigationSourceType = queryProviderType.Assembly.GetType("Microsoft.Xrm.Sdk.Linq.QueryProvider+NavigationSource");
        var linkLookupType = queryProviderType.Assembly.GetType("Microsoft.Xrm.Sdk.Linq.QueryProvider+LinkLookup");
        var linkLookupListType = listType.MakeGenericType(linkLookupType);

        object projection = null;
        object source = Activator.CreateInstance(navigationSourceType, new object[] { null, null });
        object linkLookups = Activator.CreateInstance(linkLookupListType);
        bool throwIfSequenceIsEmpty = false;
        bool throwIfSequenceNotSingle = false;

        object[] arguments = new object[6];
        arguments[0] = items.Expression;
        arguments[1] = throwIfSequenceIsEmpty;
        arguments[2] = throwIfSequenceNotSingle;
        arguments[3] = projection;
        arguments[4] = source;
        arguments[5] = linkLookups;

        var getQueryExpressionMethod = queryProviderType.GetMethod("GetQueryExpression", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, new[] {
                typeof(Expression), 
                typeof(bool).MakeByRefType(), 
                typeof(bool).MakeByRefType(),
                projectionType.MakeByRefType(),
                navigationSourceType.MakeByRefType(),
                linkLookupListType.MakeByRefType(),
            }, null);

        var queryExpression = (QueryExpression)getQueryExpressionMethod.Invoke(queryProvider, arguments);
        return queryExpression;
    }

    public static string ToXml(this QueryExpression queryExpression, IOrganizationService service)
    {
        var request = new QueryExpressionToFetchXmlRequest { Query = queryExpression };
        var response = (QueryExpressionToFetchXmlResponse)service.Execute(request);
        return response.FetchXml;
    }
}
详情如下:


提供的解决方案不适用于Chielus提到的CRM2013 SDK程序集

对于CRM2013,您可以使用以下扩展方法:

public static class QueryProviderExtensions
{
    public static QueryExpression ToQueryExpression<T>(this IQueryable<T> items)
    {
        var queryProvider = items.Provider;

        var queryProviderType = queryProvider.GetType();
        var listType = typeof(List<>);

        var projectionType = queryProviderType.Assembly.GetType("Microsoft.Xrm.Sdk.Linq.QueryProvider+Projection");
        var navigationSourceType = queryProviderType.Assembly.GetType("Microsoft.Xrm.Sdk.Linq.QueryProvider+NavigationSource");
        var linkLookupType = queryProviderType.Assembly.GetType("Microsoft.Xrm.Sdk.Linq.QueryProvider+LinkLookup");
        var linkLookupListType = listType.MakeGenericType(linkLookupType);

        object projection = null;
        object source = Activator.CreateInstance(navigationSourceType, new object[] { null, null });
        object linkLookups = Activator.CreateInstance(linkLookupListType);
        bool throwIfSequenceIsEmpty = false;
        bool throwIfSequenceNotSingle = false;

        object[] arguments = new object[6];
        arguments[0] = items.Expression;
        arguments[1] = throwIfSequenceIsEmpty;
        arguments[2] = throwIfSequenceNotSingle;
        arguments[3] = projection;
        arguments[4] = source;
        arguments[5] = linkLookups;

        var getQueryExpressionMethod = queryProviderType.GetMethod("GetQueryExpression", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, new[] {
                typeof(Expression), 
                typeof(bool).MakeByRefType(), 
                typeof(bool).MakeByRefType(),
                projectionType.MakeByRefType(),
                navigationSourceType.MakeByRefType(),
                linkLookupListType.MakeByRefType(),
            }, null);

        var queryExpression = (QueryExpression)getQueryExpressionMethod.Invoke(queryProvider, arguments);
        return queryExpression;
    }

    public static string ToXml(this QueryExpression queryExpression, IOrganizationService service)
    {
        var request = new QueryExpressionToFetchXmlRequest { Query = queryExpression };
        var response = (QueryExpressionToFetchXmlResponse)service.Execute(request);
        return response.FetchXml;
    }
}
详情如下:


我尝试了这个方法,但它只返回对象类型名称。我找到了对此的引用,但仅适用于CRM 4.0。我尝试了此操作,但它只返回对象类型名称。我找到了这方面的参考资料,但仅限于CRM 4.0。这在Dynamics CRM 2013中被打破。请参阅此博客文章以了解支持的替代方案:这在Dynamics CRM 2013中已被打破。有关受支持的备选方案,请参阅此博客: