4

単純な(思ったように)1つのタスクを処理できません。WCF サービスを介して送信したい 2 つの POCO クラスがあります。

広告クラスから派生した不動産クラス、および広告に関連する場所 (広告は多対多の関係にあるいくつかの場所に属します)

ここに私のデータ契約があります:

[DataContract]
[KnownType(typeof(Location))]
[KnownType(typeof(Estate))]
public abstract class Advert
{
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public decimal? Price { get; set; }
    [DataMember]
    public byte FromAgent { get; set; }
    [DataMember]
    public DateTime Date { get; set; }

    [DataMember]
    public virtual ICollection<Url> Urls { get; set; }
    [DataMember]
    public virtual ICollection<Location> Locations { get; set; }
    [DataMember]
    public virtual ICollection<PhoneNumber> PhoneNumbers { get; set; } 
}

[KnownType(typeof(Location))]
[DataContract]
public class Estate : Advert
{
    [DataMember]
    public byte OfferType { get; set; }

    [DataMember]
    public byte EstateType { get; set; }

    [DataMember]
    public byte MarketType { get; set; }

    [DataMember]
    public int? Area { get; set; }

    [DataMember]
    public byte? Rooms { get; set; }
}


[DataContract]
public class Location
{
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public byte Type { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string NamePrefix { get; set; }
    [DataMember]
    public string Feature { get; set; }
    [DataMember]
    public int NumberOfEstates { get; set; }

    [DataMember]
    public virtual ICollection<Location> ParentLocations { get; set; }
    [DataMember]
    public virtual ICollection<Advert> Adverts { get; set; }
}

マイ サービス インターフェイス:

    [OperationContract]
    [ServiceKnownType(typeof(Location))]
    IEnumerable<Estate> GetEstates(EstateFilter filter);

その実装:

    public IEnumerable<Estate> GetEstates(EstateFilter filter)
    {
        return EstateProcesses.GetEstates(filter);
    }

そしてビジネス層では:

    public static List<Estate> GetEstates(EstateFilter filter)
    {
        List<Estate> estates;

        if (filter==null) filter = new EstateFilter();

        using (var ctx = new Database.Context())
        {
            estates = (from e in ctx.Adverts.OfType<Estate>()
                       where
                              (filter.ID == null || e.ID == filter.ID)
                              && (filter.DateFrom == null || e.Date >= filter.DateFrom)
                              && (filter.DateTo == null || e.Date <= filter.DateTo)
                              && (filter.PriceFrom == null || e.Price >= filter.PriceFrom)
                              && (filter.PriceTo == null || e.Price <= filter.PriceTo)
                              && (filter.FromAgent == null || e.FromAgent == filter.FromAgent)
                              && (filter.LocationID == null || e.Locations.Any(l => l.ID == filter.LocationID))
                              && (filter.PhoneNumber == null || e.PhoneNumbers.Any(p => p.Number == filter.PhoneNumber))
                              && (filter.Url == null || e.Urls.Any(u => u.Address == filter.Url))
                          select e).ToList();
            foreach (var estate in estates)
            {
                ctx.LoadProperty(estate, e => e.Locations);
            }
        }

        return estates;
    }

私が得る例外はポーランド語です:

Połączenie gniazda zostało przerwane. Mogło to być spowodowane błędnym przetwarzaniem komunikatu, przekroczeniem limitu czasu odbioru przez zdalny host lub problemem z zasobami sieciowymi podległej sieci. Limit czasu lokalnego gniazda wynosi „00:00:59.9929996”.

英語では次のようになります。

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was „00:00:59.9929996”.

サーバースタックトレースは次のとおりです。

Server stack trace: 
   w System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
   w System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   w System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   w System.ServiceModel.Channels.SessionConnectionReader.Receive(TimeSpan timeout)
   w System.ServiceModel.Channels.SynchronizedMessageSource.Receive(TimeSpan timeout)
   w System.ServiceModel.Channels.FramingDuplexSessionChannel.Receive(TimeSpan timeout)
   w System.ServiceModel.Channels.FramingDuplexSessionChannel.TryReceive(TimeSpan timeout, Message& message)
   w System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(Message message, TimeSpan timeout)
   w System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   w System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   w System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   w System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   w System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   w IService.GetEstates(EstateFilter filter)
   w ServiceClient.GetEstates(EstateFilter filter)

私はこのクラスをEFのPOCOクラスとしても使用しています。

ここに問題があります。場所をロードせずに不動産を送信すると、問題なく動作します。しかし、場所を含む不動産を送信したい場合、WCFHostClient はエラーをスローします。

そして質問: 各エステートに場所の ICollection が含まれているエステートの WCF IEnumerable を介して送信する方法は?

4

1 に答える 1

0

オブジェクト ツリーには、循環依存の可能性がたくさんあります。これを場所に追加してみてください

[DataContract(IsReference=true]
public class Location

これを Advert クラスにも追加する必要がある場合があります (Advert -> Location -> advert)。ペイロードを最小限に抑えるために、オブジェクト ツリーについて検討することをお勧めします。

于 2015-05-28T19:32:41.620 に答える