将 ODATA $expand查询选项与 WebAPI 和 ViewModel 结合使用



这个问题非常相似,但没有给我我需要的东西。

我正在使用实体框架 6。 我的数据库有两个表:"客户"和"客户类型"。 我已经为每个视图模型创建了一个视图模型。 客户可以具有以下类型:

public class Customer
{
    public int CustomerID { get; set; }
    public string CustomerName { get; set; }
    public CustomerTypeViewModel CustomerType { get; set; }
}
public class CustomerTypeViewModel
{
    public int CustomerTypeID { get; set; }
    public string CustomerTypeDescription { get; set; }
}

我有一个客户控制器,它公开了一个返回类型为 IQueryable 的 odata 操作方法:

[HttpPost, Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IQueryable<CustomerViewModel> GetCustomersMatchingCriteria([FromBody]ODataActionParameters parameters)
    {
        var criteria = (CustomerMassUpdateCriteriaViewModel)parameters["Criteria"];
        return Common.Customers.GetCustomerMassUpdateCriteriaResults(criteria,
            ConfigurationManager.AppSettings["CLIENT_ID"]).Select(
            c => new CustomerViewModel()
            {
                CustomerID = c.CustomerID,
                CustomerName = c.CustomerName,
                CustomerType = new CustomerTypeViewModel() 
                {
                    CustomerTypeDescription = c.CustomerType.CustomerTypeDescription
                }
            });
    }

方法只返回一个 IQueryable of Customer,即实际实体。

问题是,使用以下查询字符串选项调用此控制器方法时:

$expand=CustomerType
$select=CustomerID,CustomerName,CustomerType/CustomerTypeDescription

引发此异常:

"

对象内容"1"类型无法序列化内容类型的响应正文'应用程序/json;charset=utf-8'.","type":"System.InvalidOperationException"

DbIsNull表达式的参数必须引用基元、枚举或引用类型。

从$select列表中删除$expand选项和关联的客户类型/客户类型说明属性不会产生错误。

我觉得我在这里错过了一些明显的东西。 有什么想法吗?

第一次编辑:

通过 ToList() 扩展方法枚举结果并返回 IEnumerable 而不是 IQueryable 成功扩展了 CustomerType 导航属性,但我的 ODATA $select列表在数据库级别不再得到尊重。 这不会破坏使用 ODATA 的目的吗?

异常 :

"

对象内容"1"类型无法序列化 的响应正文 内容类型"应用程序/JSON"; charset=utf-8'.","type":"System.InvalidOperationException"

据我所知,这是由于请求如何达到 OData 格式。请求应转到 OData 路由进行格式化。如果你可以在 global.asax 中的 RouteConfig.RegisterRoutes 和 WebApiConfig.Register 之前移动 GlobalConfiguration.Configuration.EnableOData() 可能会有所帮助。

最新更新