1

我正在创建一个供移动应用程序以及我们的 ASP.NET MVC4 webapp 使用的 WebAPI。我们正在使用一个庞大的数据库,因此我们需要尽可能避免实体化实体列表。我们的 WebAPI 返回 JSON。

情况很简单...收到了对许可证列表的请求,但必须对其进行分页,因为有 500,000 条记录可以返回。在将实体列表转换为返回的视图模型列表之前,如何将分页/过滤应用于实体列表?

这是我正在使用的一些测试代码...

    // Get the list of licenses, but page them.
    // GET api/<controller>
    //[Queryable] 
    public IQueryable<LicenseViewModel> Get()
    {
        Mapper.CreateMap<LicenseEntity, LicenseViewModel>();
        Mapper.AssertConfigurationIsValid();

        List<LicenseViewModel> vms = new List<LicenseViewModel>();
        using (var repo = new LicenseRepository())
        {
            // Get the IQueryable<LicenseEntity> list...
            // IS THERE SOME WAY TO APPY PAGING/FILTERING HERE?
            var entities = repo.List();

            // Convert them to viewmodels.  ARGGG! This will materialize the huge list
            // if we cannot applyfiltering/paging in the previous step.
            foreach (var item in entities)
            {
                var vm = Mapper.Map<LicenseEntity, LicenseViewModel>(item);
                list.Add(vm);
            }
        }

        return vms.AsQueryable();
    }

我尝试了以下操作,但是当我尝试展开列表并查看结果时收到“无法评估儿童”错误。

            using (var repo = new LicenseRepository())
            {
                // Get the list of entities...
                var list = repo
                    .List()
                    .Select(x => Mapper.Map(x, new LicenseViewModel()));

                return list;
            }

感谢您的时间和建议,

麦克风

4

4 回答 4

0

// 获取 LicenseEntity 对象的 IQueryable 列表。var entityList = LicenseRepository.List(适配器);

// 将列表转换为 // LicenseViewModel 对象的 IQueryable 列表。var vmList = entityList.Select(x => AutoMapper.Mapper.Map(x, new LicenseViewModel()));

于 2012-11-30T16:55:47.210 回答
0

我找到了将域实体投影到视图模型的解决方案。如果您遇到与我相同的问题,请查看以下链接:

http://lostechies.com/jimmybogard/2011/02/09/autoprojecting-linq-queries/ http://www.devtrends.co.uk/blog/stop-using-automapper-in-your-data-access-代码

顺便说一句,在一个我的域实体中,我有一个带有一些“计算”属性的部分类......其值是从数据库记录中的其他字段生成的属性。这些不能在域实体中,因为它们会干扰上述解决方案。我将它们移至我的 ViewModel 类,这是真正需要它们的地方,一切都很好。

希望这些信息能帮助...

麦克风

于 2012-12-01T07:17:04.880 回答
0

不确定这如何映射到 Web API,但主体是相同的。

使用 WCF Dataservices 本质上是相同的,但我相信目前有一些额外的功能,您可以将页面大小设置如下:

 public static void InitializeService(DataServiceConfiguration config)
 {
        config.SetEntitySetPageSize("*", 20);
 }

其中“*”是插入您的实体集名称。

通过设置此项,Feed 将包含一个继续令牌,客户端可以使用该令牌请求下一页。

在您的存储库中,您可能需要根据您的数据源手动处理 Take 和 Skip 函数。

如果 URL 包含 ?$top=10&$skip=0 那么您可以将其添加到来自数据源的请求中,请参见下面的示例。

using (var repo = new LicenseRepository())
{
     // Get the list of entities...
     var list = repo                        
     .Select(x => Mapper.Map(x, new LicenseViewModel()))
     .Skip(0)
     .Take(10);
     return list;
}

显然,根据 URL 的 $top 和 $skip 元素中的内容更改 skip/take 值。

于 2012-11-29T22:24:43.043 回答
0

对于分页,您可以使用我们最近添加的 ResultLimit 功能。你可以说,

[Queryable(ResultLimit=10)] 

一次只退回 10 件商品。

而且,最酷的部分是我们还计算了下一页链接。下一页链接是客户端获取下一页应遵循的链接。如果您使用的是 ODataFormatter,则下一页链接默认包含在响应中。如果您使用不同的格式化程序,我们只计算链接但不将其放入响应正文中,因为我们不知道它的格式。您可以编写消息处理程序或操作过滤器来检索链接

Request.Properties['MS_NextPageLink'] 

并将其写入响应正文或响应标头或客户期望的任何位置。

于 2012-11-30T03:14:15.047 回答