2013-10-07 21 views
0

如何在WebAPI中实现这种“智能”GET?我有两个班,我想从我的服务中获得。让我们说它的书店与书籍对象有关系。使用循环依赖和可加载列表实现WebAPI

public class Book 
{ 
    Guid Id { get; set; } 
    string Title { get; set; } 
    Store Store { get; set; } 
} 

public class Store 
{ 
    Guid Id { get; set; } 
    string Title { get; set; } 
    string Owner { get; set; } 
    IEnumerable<Book> Books { get; set; } 
} 

我有代码中的SQL服务器和EntityFramework适配器的后端。我应该怎样才能在需要之后返回书目清单(请求),就像OData一样? 正如你所看到的我有循环依赖,这使得我的JSON序列化器显示错误。我解决它:

config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize; 
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; 

但序列化的所有数据和我的回应是巨大的,这是不适合我的Windows Phone应用程序。在某些情况下,我只需要Store对象,但在其他情况下,我需要Store与所有参考书籍。

在控制器中,我使用[Queryable]属性来使用OData查询。 P.S.我无法创建更多的Web方法,如GetBooks,GetStore等。它应该是一种方法。

我该如何解决我的问题?

+0

为什么你不能创建更多的方法,如'GetBooks'和'GetStore'?为什么它只能是一种方法? – danludwig

回答

1

我该如何解决我的问题?

不要从您的API操作方法返回实体。

取而代之的是返回模型。

因此,不是这样的:

public IEnumerable<Store> GetStores() 
{ 
    using (var db = new MyDbContext()) 
    { 
     return db.Stores; 
    } 
} 

做这样的事情:

public IEnumerable<StoreModel> GetStores() 
{ 
    using (var db = new MyDbContext()) 
    { 
     var entities = db.Stores; 
     return entities.Select(x => new StoreModel 
     { 
      Id = x.Id, 
      Title = x.Title, 
      Owner = x.Owner, 
      Books = x.Books.Select(y => new BookModel 
      { 
       Id = y.Id, 
       Title = y.Title, 
       StoreId = x.Id, 
      }), 
     }); 
    } 
} 

通过做这种方式可以消除循环依赖关系图。 Book不再提及Store,只有StoreId

0

您需要使其超媒体驱动。书籍和商店可以被认为是不同的资源。当针对特定图书发出GET请求时,如@danlugwig所建议的,您可以返回书籍模型以及相应商店的URI。消费者可以使用此URI来检索商店详情。同样适用于Store资源。

+0

谢谢,这解释了我很多。为每个实体使用不同的方法。 – Tomas