由于DTO映射,OdataController查询计划不是最佳的

时间:2013-12-03 16:18:11

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

将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时,查询未选择SubObjects。

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

我正在寻找解决此问题的最佳位置,我可能会设置一个选择展开的ODataQueryOption,它可以伪造一个选择或扩展调用,但我不确定这是否可行。

1 个答案:

答案 0 :(得分:0)

如果其他人遇到此问题,这就是我所做的修复它。 select扩展查询应该从请求上下文中的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
       }
    });
}