如何按需排除Web API中的属性

时间:2014-03-27 15:42:13

标签: c# linq asp.net-web-api

我是WebApi的新手,所以请原谅这个问题是否是业余的:我使用AngularJS" $ resource"与WebApi-Controller" BondController"进行通信。这非常有效。 我的问题:实体"邦德"引用实体列表" Price":

public class Bond
{
    public int ID { get; set; }
    ...
    public virtual List<Price> Prices { get; set; }
}

我正在寻找的方法是排除嵌套列表&#34;价格&#34; ,例如

[JsonIgnore]

但是,在某些其他情况下,我仍然需要一种方法来检索包括此嵌套列表的债券,例如通过第二个控制器&#34; Bond2&#34;。

我该怎么办?

我是否需要在实体Bond之上使用一些ViewModel? 我可以以某种方式排除控制器本身的价格清单:

public IQueryable<Bond> GetBonds()
{
     return db.Bonds [ + *some Linq-Magic that excludes the list of Prices*]
}

背景:价格列表可能会变得相当长,而Get-Requests很容易变成&gt; 1MB。在大多数情况下,甚至不需要向用户显示价格,因此我想将它们排除在响应之外。但在一个案例中,他们会......感谢您的投入!

修改 我看到,对于某种Linq Magic,我需要一种新型的#34; PricelessBond&#34;

EDIT2 找到了一个使用DTO here的好例子,并将使用它。

解决方案是创建一个非持久性BondDTO类,充当&#34; shell&#34;并且只有那些你希望在某个用例中可见的属性,然后在BondDTOController中转换Bond =&gt;的选择。 BondDTO通过Linq Lambda Select表达式。

1 个答案:

答案 0 :(得分:1)

我不是WebApi的专家,但似乎你有多个问题。 为什么不创建类层次结构?

public class PricelessBond // :)
{
    public int ID {get; set;}
}

public class Bond : PricelessBond
{
    public List<Price> Prices {get; set;}
}

然后,您可以通过两种不同的方法公开数据:

public class BondsController : ApiController
{
    [Route("api/bonds/get-bond-without-price/{id}")]
    public PricelessBond GetBondWithoutPrice(int id)
    {
        return DataAccess.GetBondWithoutPrice(id);
    }

    [Route("api/bonds/get-bond/{id}")]
    public Bond GetBond()
    {
        return DataAccess.GetBond(id);
    }
}

在你的DataAccess课程中:

public class DataAccess
{
    public PricelessBond GetBondWithoutPrice(int id)
    {
        return db.Bonds
            .Select(b => new PricelessBond
            {
                ID = b.ID
            })
            .Single(b => b.ID == id);
    }

    public Bond GetBond(int id)
    {
        return db.Bonds
            .Select(b => new Bond
            {
                ID = b.ID,
                Prices = b.Prices.Select(p => new Price{}).ToArray()
            })
            .Single(b => b.ID == id);
    }
}

当然,使用两种数据访问方法意味着一些代码开销,但是由于您说响应可能大于1MB,这也意味着您应该节省数据库服务器而不是获取您不需要的数据。 / p>

因此,在您的数据访问层中,只加载每个操作所需的数据。

我已经在一个临时项目中对此进行了测试,但它确实有用。