0

如何在 WebAPI 中实现这样的“智能”GET?我想从我的服务中获得 2 个课程。假设它的书店与书籍对象有关。

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 查询。PS 我无法创建更多的网络方法,如 GetBooks、GetStore 等。它应该是一种方法。

我该如何解决我的问题?

4

2 回答 2

2

我该如何解决我的问题?

不要从您的 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

于 2013-10-07T12:55:16.550 回答
0

你需要让它成为超媒体驱动的。书籍和商店可以被认为是不同的资源。当针对特定书籍发出 GET 请求时,就像@danlugwig 建议的那样,您可以返回书籍模型及其相应商店的 URI。消费者可以使用此 URI 来检索商店详细信息。商店资源也是如此。

于 2013-10-08T08:58:22.637 回答