我在客户端和服务器端分割了.Net应用程序,服务器提供REST服务(使用WCF)。我有这样的服务定义:
[WebGet(UriTemplate = "/Customers/{id}")]
Customer GetCustomerById(string id);
[WebGet(UriTemplate = "/Customers")]
List<Customer> GetAllCustomers();
使用Fluent NHibernate和Lazy Loading将Customer类及其朋友映射到数据库。如果我从会话范围之外的服务返回,则服务调用将失败,因为它无法序列化引用的延迟加载的Orders属性(请参阅末尾的类def)。问题是我需要延迟加载,因为我不希望我的GetAllCustomers
- 服务获取所有引用的订单。所以我想做的是以某种方式通知序列化程序,以便它不会尝试序列化GetAll上的Orders。但请注意,必须在GetCustomerById上序列化相同的属性 - 因此我必须在服务上指定此属性。可以这样做吗?!
课程:
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Order> Orders { get; set; }
}
public class Order
{
public virtual int Id { get; set; }
// ++
}
答案 0 :(得分:3)
如果您正在使用WCF的默认序列化 - 我认为您这样做 - 您将明确标记要通过网络发送的属性,并保留其余部分。这是使用[DataMember]
完成的,我假设你这样做:
[DataContract]
public class Customer
{
[DataMember]
public virtual int Id { get; set; }
[DataMember]
public virtual string Name { get; set; }
// not decorate
public virtual IList<Order> Orders { get; set; }
}
<强>更新强> 好的,你需要有时发送而不发送其他时间。显然,您可以拥有CustomerBase类(没有订单),然后是Customer(订单未装饰)和CustomerWithOrders(装饰订单)。从每个操作中发送每个操作。
如果这不适合您,请在此处使用DataContractSerializerOperationBehavior
和IDataContractSurrogate
查看自定义序列化:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.idatacontractsurrogate.aspx
答案 1 :(得分:2)
为不同的场景设置不同的DTO,然后使用Automapper将你的nhib对象转移到DTOs - 这样你就可以为每个案例设置一个特殊的对象图,然后你就无法进行迭代,从而为你的集合提供保湿不想。
答案 2 :(得分:1)
我要为GetAllCustomers
服务返回不同的数据协定。如,
[DataContract]
public class CustomerSummary
{
// Have properties that represent the summary of the customer
}
WebGet(UriTemplate = "/Customers/{id}")]
Customer GetCustomerById(string id);
[WebGet(UriTemplate = "/Customers")]
List<CustomerSummary> GetAllCustomers();
或者,在将EmitDefaultValue
属性应用于DataMember
属性时使用Orders
:
[DataContract]
public class Customer
{
[DataMember]
public virtual int Id { get; set; }
[DataMember]
public virtual string Name { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public virtual IList<Order> Orders { get; set; }
}
然后在GetAllCustomers
返回数据时将Orders属性保留为null。
答案 3 :(得分:0)
延迟加载仅适用于hibernate会话的范围。没有机会通过电线做这件事。您需要急切地获取集合或使用OOP继承,并从Web方法返回一个根本没有此集合的类,特别是如果消费者不需要它。