1

サーバー (fluentNHibernate を使用するサーバー) からクライアントのリストを取得しようとしています。クライアント オブジェクトは次のとおりです。

[DataContract]
//[KnownType(typeof(System.Collections.Generic.List<ContactPerson>))]
//[KnownType(typeof(System.Collections.Generic.List<Address>))]
//[KnownType(typeof(System.Collections.Generic.List<BatchRequest>))]
//[KnownType(typeof(System.Collections.Generic.List<Discount>))]
[KnownType(typeof(EClientType))]
[KnownType(typeof(EComType))]
public class Client
{
    #region Properties

[DataMember]
public virtual int ClientID { get; set; }

[DataMember]
public virtual EClientType ClientType { get; set; }

[DataMember]
public virtual string RegisterID {get; set;}

[DataMember]
public virtual string HerdCode { get; set; }

[DataMember]
public virtual string CompanyName { get; set; }

[DataMember]
public virtual bool InvoicePerBatch { get; set; }

[DataMember]
public virtual EComType ResultsComType { get; set; }

[DataMember]
public virtual EComType InvoiceComType { get; set; }



//[DataMember]
//public virtual IList<ContactPerson> Contacts { get; set; }

//[DataMember]
//public virtual IList<Address> Addresses { get; set; }

//[DataMember]
//public virtual IList<BatchRequest> Batches { get; set; }

//[DataMember]
//public virtual IList<Discount> Discounts { get; set; }

#endregion

#region Overrides

public override bool Equals(object obj)
{
    var other = obj as Client;
    if (other == null)
        return false;
    return other.GetHashCode() == this.GetHashCode();
}

public override int GetHashCode()
{
    return ClientID.GetHashCode() | ClientType.GetHashCode() | RegisterID.GetHashCode() |
            HerdCode.GetHashCode() | CompanyName.GetHashCode() | InvoicePerBatch.GetHashCode() |
            ResultsComType.GetHashCode() | InvoiceComType.GetHashCode();// | Contacts.GetHashCode() |
            //Addresses.GetHashCode() | Batches.GetHashCode() | Discounts.GetHashCode();
}

#endregion
}

サブリストを削除しようとしましたが、この簡略化されたバージョンのクライアントでも問題が発生します。

私の流暢なマッピングは次のとおりです。

public class ClientMap : ClassMap<Client>
    {
        public ClientMap()
        {
            Table("Clients");
            Id(p => p.ClientID);

            Map(p => p.ClientType).CustomType<EClientType>(); ;
            Map(p => p.RegisterID);
            Map(p => p.HerdCode);
            Map(p => p.CompanyName);
            Map(p => p.InvoicePerBatch);
            Map(p => p.ResultsComType).CustomType<EComType>();
            Map(p => p.InvoiceComType).CustomType<EComType>();

            //HasMany<ContactPerson>(p => p.Contacts)
            //    .KeyColumns.Add("ContactPersonID")
            //    .Inverse()
            //    .Cascade.All();

            //HasMany<Address>(p => p.Addresses)
            //    .KeyColumns.Add("AddressID")
            //    .Inverse()
            //    .Cascade.All();

            //HasMany<BatchRequest>(p => p.Batches)
            //    .KeyColumns.Add("BatchID")
            //    .Inverse()
            //    .Cascade.All();

            //HasMany<Discount>(p => p.Discounts)
            //    .KeyColumns.Add("DiscountID")
            //    .Inverse()
            //    .Cascade.All();

        } 

以下に示すクライアント メソッドは、サーバーに接続します。サーバーはリストを取得し、すべてがオブジェクトに正しく表示されますが、返されたときにクライアントは何も受け取りません (List オブジェクトを受け取りますが、その中には何もありません。

呼び出し方法は次のとおりです。

public List<s.Client> GetClientList()
        {
            try
            {
                s.DataServiceClient svcClient = new s.DataServiceClient();
                svcClient.Open();

                List<s.Client> clients = new List<s.Client>();

                clients = svcClient.GetClientList().ToList<s.Client>();

                svcClient.Close(); //when receiving focus from server, the clients object has a count of 0

                return clients;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
            return null;
        }

そしてサーバーメソッド:

public IList<Client> GetClientList()
        {
            var clients = new List<Client>();

            try
            {
                using (var session = SessionHelper.OpenSession())
                {
                    clients = session.Linq<Client>().Where(p => p.ClientID > 0).ToList<Client>();
                }
            }
            catch (Exception e)
            {
                EventLog.WriteEntry("eCOWS.Data", e.Message);
            }

            return clients; //returns a list with 1 client in it
        }

サーバー メソッド インターフェイスは次のとおりです。

 [UseNetDataContractSerializer]
        [OperationContract]
        IList<Client> GetClientList();

最後の参考として、クライアントの app.config エントリを次に示します。

 <system.serviceModel>

        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IDataService" listenBacklog="10" maxConnections="10"
                         transferMode="Buffered" transactionProtocol="OleTransactions"
                         maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" 
                         receiveTimeout="00:10:00" sendTimeout="00:10:00">
                      <readerQuotas maxDepth="51200000" maxStringContentLength="51200000" 
                                    maxArrayLength="51200000" maxBytesPerRead="51200000" 
                                    maxNameTableCharCount="51200000" />
                  <security mode="Transport"/>
                </binding>
            </netTcpBinding>
        </bindings>

        <client>
            <endpoint address="net.tcp://localhost:9000/eCOWS/DataService"
                binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IDataService"
                contract="eCowsDataService.IDataService" name="NetTcpBinding_IDataService"
                behaviorConfiguration="eCowsEndpointBehavior">
            </endpoint>

           <endpoint address="MEX"
                     binding="mexHttpBinding"
                     contract="IMetadataExchange" />

        </client>

        <behaviors>
          <endpointBehaviors>
            <behavior name="eCowsEndpointBehavior">
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
          </endpointBehaviors>
        </behaviors>

    </system.serviceModel>

そして私のサーバーapp.config:

    <system.serviceModel>

      <bindings>
        <netTcpBinding>
          <binding name="netTcpBinding"
                   maxConnections="10" listenBacklog="10"
                   transferMode="Buffered" transactionProtocol="OleTransactions" 
                   maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
                   sendTimeout="00:10:00" receiveTimeout="00:10:00">
            <readerQuotas maxDepth="51200000" maxStringContentLength="51200000" 
                          maxArrayLength="51200000" maxBytesPerRead="51200000" 
                          maxNameTableCharCount="51200000" />
            <security mode="Transport"/>
          </binding>
        </netTcpBinding>
      </bindings>

      <services>
      <service name="eCows.Data.Services.DataService" behaviorConfiguration="eCowsServiceBehavior">

        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:9001/eCOWS/" />
            <add baseAddress="net.tcp://localhost:9000/eCOWS/" />
          </baseAddresses>
        </host>

        <endpoint address="DataService" 
                  binding="netTcpBinding" 
                  contract="eCows.Data.Services.IDataService"
                  behaviorConfiguration="eCowsEndpointBehaviour">
        </endpoint>

        <endpoint address="MEX"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>

    <behaviors>
      <endpointBehaviors>
        <behavior name="eCowsEndpointBehaviour">
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
        </behavior>
      </endpointBehaviors>      
      <serviceBehaviors>
        <behavior name="eCowsServiceBehavior">
          <serviceMetadata httpGetEnabled="True"/>
          <serviceThrottling maxConcurrentCalls="10" maxConcurrentSessions="10"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
        <behavior name="MexBehaviour">
          <serviceMetadata />
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

以前は「ソケットのクローズ/ネットワークまたはタイムアウト」エラーが発生していましたが、トレースは、コールバックでリスニング エンドポイントを探していたものの、エンドポイントが見つからなかったことを明確に示していました。とにかく、 UseNetSerializer を追加した後、そのエラーはなくなりましたが、今は何も得られません。

PS。コメントアウトされたすべてのリスト項目を追加すると、DB からエントリを取得できますが、クライアントでは何も受信されません。

[UseNetDataContractSerializer] を削除すると、svclog に次のエラーが表示されます。

警告: 説明 Faulted System.ServiceModel.Channels.ServerSessionPreambleConnectionReader+ServerFramingDuplexSessionChannel

警告: 説明 Faulted System.ServiceModel.Channels.ServiceChannel

エラー: [eCows.Data.Models.Client#3] の初期化 - ロールのコレクションの遅延初期化に失敗しました: eCows.Data.Models.Client.Addresses、セッションまたはセッションが閉じられませんでした

...

エラー: ServiceModel クライアント構成セクションでコントラクト 'ILogbookManager' を参照する既定のエンドポイント要素が見つかりませんでした。これは、アプリケーションの構成ファイルが見つからなかったか、このコントラクトに一致するエンドポイント要素がクライアント要素に見つからなかったためである可能性があります。

.Not.LazyLoad を List マッピング項目に追加すると、エラーが返されなくなりますが、クライアント情報も受信されません。

4

1 に答える 1

1

WCFでは、インターフェイスではなく具象型を使用する必要があります。List<Client>の代わりにを使用して開始するIList<Client>か、単純な配列を使用しますClient[]。(インターフェースを使用することは可能ですが、それはもっと多くの作業です。)

ここでの実際の問題は、Linqがデータコントラクトで指定できないランタイムタイプを返すことです。

サーバーメソッドのサンプルコピー:

public Client[] GetClientList()
{
    try
    {
        using (var session = SessionHelper.OpenSession())
        {
            return session.Linq<Client>().Where(p => p.ClientID > 0).ToArray<Client>();
        }
    }
    catch (Exception e)
    {
        EventLog.WriteEntry("eCOWS.Data", e.Message);
        return null;
    }
}
于 2010-04-15T21:41:00.163 に答える