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。如果我添加所有已注释掉的列表项,我仍然会从数据库中检索一个条目,但在客户端上仍然没有收到任何内容。

如果我删除 [UseNetDataContractSerializer] 我会在 svclog 中收到以下错误:

警告:描述故障 System.ServiceModel.Channels.ServerSessionPreambleConnectionReader+ServerFramingDuplexSessionChannel

警告:描述故障 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 回答