0

エンティティ フレームワークからデータを返す WCF サービスがあります。返されるオブジェクトは、注文の子である OrderLine の子である ShippingLine です。

私のWCFサービスには、次のコードがあります。

            var shippingLine = _dbContext.ShippingLines
                            .Include(l => l.OrderLine)
                            .Include(l => l.OrderLine.Order)
                            .Include(l => l.OrderLine.Order.Customer)
                            .Include(l => l.OrderLine.Order.Customer.CustomerAddress)
                            .Include(l => l.OrderLine.Order.Customer.CustomerAddress.Country)
                            .Include(l => l.OrderLine.Order.Customer.CustomerAddress.State)
                            .Include(l => l.OrderLine.OrderLineOptions)
                            .Include(l => l.OrderLine.OrderLineOptions.First().Option)
                            .Include(l => l.OrderLine.OrderLineOptions.First().Option.ExternalPrintingSystemMapping)
                            .Include(l => l.OrderLine.OrderLineStatus)
                            .Include(l => l.TrackingNumbers)
                            .Include(l => l.ShippingMethod)
                            .Include(l => l.ShippingMethod.ShippingRates)
                            .Include(l => l.ShippingBox)
                            .Include(l => l.BulkMailingAsset)
                            .Include(l => l.BulkPostageType)
                            .FirstOrDefault<ShippingLine>(line => line.Id == id);

単体テストの作成を支援するために、EF およびセルフ トラッキング エンティティに関するいくつかのカスタム拡張メソッドを使用しています。上記で呼び出されている独自の Include メソッドを実装しました。

            public static IQueryable<TSource> Include<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, object>> exp) where TSource : class
        {
            var objectQuery = source as ObjectQuery<TSource>;

            if (objectQuery != null)
            {
                return objectQuery.Include(ObjectQueryExtensionMethods.GetIncludePath((MemberExpression)exp.Body));
            }

            var fakeObjectSet = source as FakeObjectSet<TSource>;
            if (fakeObjectSet != null)
            {
                fakeObjectSet.Include(exp);
            }

            return source;
        }

        public static IQueryable<TSource> Include<TSource>(this IQueryable<TSource> source, string path) where TSource : class
        {
            var objectQuery = source as ObjectQuery<TSource>;

            if (objectQuery != null)
            {
                return objectQuery.Include(path);
            }

            var fakeObjectSet = source as FakeObjectSet<TSource>;
            if (fakeObjectSet != null)
            {
                fakeObjectSet.Include(path);
            }

            return source;
        }

一番上の方法は、私が現在使用しているものです。「Orderline.Order.Customer」のような文字列ページを取る 2 番目のものを使用してみましたが、動作は変わりません。一番上の Include メソッドは、このメソッドを使用してインクルード パスを取得しています。

        internal static string GetIncludePath(MemberExpression memberExpression)
    {
        string path = "";
        if (memberExpression.Expression is MethodCallExpression)
            path = GetIncludePath((MemberExpression)((memberExpression.Expression as MethodCallExpression).Arguments[0])) + ".";
        if (memberExpression.Expression is MemberExpression)
            path = GetIncludePath((MemberExpression)memberExpression.Expression) + ".";

        return path + memberExpression.Member.Name;
    }

次に、この出荷ラインを MVC コントローラーに返します。MVC コントローラーは、OrderLine オブジェクトの Order にアクセスしようとします。何らかの理由で、OrderLine オブジェクトのすべてのプロパティが null であるか、デフォルト値に設定されています。Order が null であるため、次のコードでは Order オブジェクトにアクセスできません。

line.OrderLine.Order.Customer.CustomerAddress;

私は 4.0 フレームワークと EF 4 Self Tracking Entities を使用しています。

デバッガーでは、クライアントに返される前に OrderLine と Order を正しく確認できるため、OrderLine と Order の情報が含まれていることは確かです。

ただし、クライアントに到着すると、すべての OrderLine プロパティが null またはデフォルトであり、Order は存在しません。他のすべてのインクルードは正常に機能しているようです。

関係は、Order (1) から OrderLine (多数)、OrderLine (1) から ShippingLine (多数) です。

私はこれまでに試しました... 1.クライアントでサービス参照を更新します。2. クライアントでサービス参照を削除して再作成します。3. クライアントで詳細な WCF トレースをオンにします。トレースに問題は見られませんでした。

含まれているオブジェクトがそのようにドロップされる理由について何か考えはありますか?
ここに画像の説明を入力

ここに私のクライアントのweb.configがあります:

  <system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_IMyService" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferSize="2147483646" maxBufferPoolSize="2147483646" maxReceivedMessageSize="2147483646" messageEncoding="Mtom">
      <readerQuotas maxDepth="256" maxStringContentLength="5242880" maxArrayLength="2147483646" maxBytesPerRead="4096" maxNameTableCharCount="2147483646" />
      <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost/MyService/systemservice.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService" contract="MyService.IMyService" name="BasicHttpBinding_IMyService" />
</client>

これが私のWebサービスweb.configです:

    <system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
    <services>
        <service name="MyApi.MyService">
            <endpoint behaviorConfiguration="MyServiceBehavior" binding="basicHttpBinding" bindingConfiguration="MyServiceBindingConfiguration"
                contract="MyApi.IMyService"/>
            <host>
                <timeouts openTimeout="00:05:00"/>
            </host>
        </service>
    </services>
    <bindings>
        <basicHttpBinding>
            <binding name="MyServiceBindingConfiguration" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
                maxBufferSize="2147483646" maxBufferPoolSize="2147483646" maxReceivedMessageSize="2147483646" messageEncoding="Mtom">
                <readerQuotas maxDepth="256" maxStringContentLength="5242880" maxArrayLength="2147483646" maxBytesPerRead="4096" maxNameTableCharCount="5242880"/>
            </binding>
            <binding name="ServiceSoap" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false"
                bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
                <security mode="Transport">
                    <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
                    <message clientCredentialType="UserName" algorithmSuite="Default"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <!-- productionProxyAddress https://api.authorize.net/soap/v1/Service.asmx -->
        <endpoint address="https://apitest.authorize.net/soap/v1/Service.asmx" binding="basicHttpBinding" bindingConfiguration="ServiceSoap"
            contract="AuthorizeNet.ServiceSoap" name="ServiceSoap"/>
    </client>
    <behaviors>
        <endpointBehaviors>
            <behavior name="MyServiceBehavior">
            </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior>
                <serviceMetadata httpGetEnabled="True"/>
                <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>
4

2 に答える 2

0

ServiceInterface と呼ばれる (サービスではなく) プロジェクトを参照することで解決しました。このプロジェクトの唯一の目的は、Web サービスへのサービス参照を持つことです。サービスはいくつかの場所で参照されるため、新しいメソッドを追加するときに簡単になります。サービス参照を 1 か所で更新するだけで済みます。

考えられる唯一のことは、何らかの理由で、サービス参照を追加したときに、MVC サイト プロジェクトで作成されていたプロキシ クラスが正しく作成されていなかったことです。何度更新したり、サービス参照を再作成したりしても、機能しませんでした。私が知っていたサービス参照を持つプロジェクトを使用すると、うまくいきました。

于 2013-10-18T18:10:17.007 に答える
0

コレクションを含めるためのEF includeラムダ構文は

.Include(l => l.OrderLine.OrderLineOptions.Select(ol => ol.Option)) 

それよりも

.Include(l => l.OrderLine.OrderLineOptions.First().Option)
于 2013-10-17T15:50:25.073 に答える