【问题标题】:OdataController query plan not optimal because of DTO mapping由于 DTO 映射,OdataController 查询计划不是最优的
【发布时间】:2013-12-05 15:56:19
【问题描述】:

将 DAL 对象映射到 DTO 对象时,我收到了一个意外查询。

我有一些 DAL 对象:

public class MainDalObject 
{
   public Guid Id { get; set;}
   public string Description { get; set; }
   public ICollection<SubDalObject> Subs { get; set; }
}

public class SubDalObject 
{
   public Guid Id { get; set;}
   public string Description { get; set; }
   public MainDalObject Main { get; set; }
}

还有我的 DTO 课程:

public class MainObject 
{
   public Guid Id { get; set;}
   public string Name { get; set; }
   public IEnumerable<SubObject> Subs { get; set; }
}

public class SubObject 
{
   public Guid Id { get; set;}
   public string Name { get; set; }
   public MainDalObject Main { get; set; }
}

我的 MainObject 控制器包含一个 IQueryable 方法:

public IQueryable<MainObject> Get() 
{
   return (from m in Context.Get<MainDalObject>()
    select new MainObject 
    {
       Id = m.Id,
       Name = m.Description,
       Subs = m.Subs.Select(s => new SubObject 
       {
          Id = s.Id,
          Name = s.Name
       }
    });
}

这工作正常,但查询不是最佳的。当我在 /api/MainObject 上触发查询时,我根本没有选择子项。但是当我查看查询时,它无论如何都在选择子项。

但是,当我将查询更改为 /api/MainObject?$select=Id,Name 时,查询并未选择子对象。

所以我期待的是,在 WebApi 框架的某个地方,当没有使用 SelectExpandFilter 时,响应编写器正在执行 ToList(),而不指定 Select 语句。

我正在寻找解决此问题的最佳位置,我可能会设置一个 select expand ODataQueryOption,它可能会伪造一个 select 或 expand 调用,但我不确定这是否是可行的方法。

【问题讨论】:

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


    【解决方案1】:

    如果其他人遇到这个问题,这就是我为解决它所做的。选择扩展查询应该从请求上下文中的 edmmodel 派生,但这基本上是它的工作原理。

    public virtual IQueryable<TDTO> Get(ODataQueryOptions queryOptions)
            {
                if (queryOptions.SelectExpand == null)
                {
                    var selectOption = new SelectExpandQueryOption("Id,Name", string.Empty, queryOptions.Context);
                    Request.SetSelectExpandClause(selectOption.SelectExpandClause);
                }
    
                return (from m in Context.Get<MainDalObject>()
        select new MainObject 
        {
           Id = m.Id,
           Name = m.Description,
           Subs = m.Subs.Select(s => new SubObject 
           {
              Id = s.Id,
              Name = s.Name
           }
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-15
      • 2021-08-13
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      • 1970-01-01
      • 2019-10-20
      相关资源
      最近更新 更多