gpt4 book ai didi

odata - 如果 DTO 具有派生类,则使用 OData 选择的 Automapper 投影会抛出错误

转载 作者:行者123 更新时间:2023-12-05 06:44:24 24 4
gpt4 key购买 nike

使用 OData 的 Automapper 投影工作正常,正如预期的那样,但是如果我从 DTO 派生一个类,它会导致以下错误:

"exceptionMessage": "The 'TypeIs' expression with an input of type 'EmployeeDTO' and a check of type 'DeveloperDTO' is not supported. Only entity types and complex types are supported in LINQ to Entities queries.",
"exceptionType": "System.NotSupportedException",

具有讽刺意味的是,派生类不是投影中使用的类,甚至没有被映射。

为了更好地理解问题,我能够使用 Northwind 数据库简化问题。这是代码:

public class EmployeeDTO
{
public int EmployeeID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}

public class DeveloperDTO : EmployeeDTO
{
}

public class EmployeesController : ApiController
{
[HttpGet]
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.Select)]
public IHttpActionResult Get()
{
Mapper.CreateMap<Employee, EmployeeDTO>();

var dbContext = new NORTHWNDEntities();
var models = dbContext.Employees;

var dtos = models.Project().To<EmployeeDTO>();
return Ok(dtos);
}
}

使用此 OData 调用调用此 Controller 是导致错误的原因:

http://<hostname>/api/employees/get?$select=LastName

这仅在使用 OData 选择功能时发生。我试过的其他方法(skip、top、orderby)都没有问题。

现在有趣的部分来了。只需注释掉 DeveloperDTO 类定义的基类 (EmployeeDTO) 和 OData 选择函数就可以正常工作。如您所见,甚至没有使用 DeveloperDTO 类。它没有映射,在整个项目中绝对没有用。

这是针对 OData 4.0 v5.4 的 Visual Studio 2013、.NET4.5、Wep API 2.2、Automapper 3.3.1 和 Microsoft ASP.NET Web API 2.2。

重现问题:

  1. 创建新的 Web API 2 应用程序。
  2. 添加“ADO.NET 实体数据模型”的新项目并选择“来自数据库的 EF 设计器”。选择“Northwind”数据库,选择“Employees”表(Northwind 对 Entity Framework 不友好)。
  3. 使用 Nuget 添加“Automapper”和“用于 OData 4.0 的 Microsoft ASP.NET Web API 2.2”
  4. 添加新项“WEb API 2 Controller - Empty”并将其命名为“EmployeesController”。用上面列出的代码替换默认类。不要忘记包含两个 DTO 类。

使用上面发布的 URL 运行该应用程序,您将收到错误消息。注释掉 DeveloperDTO 类,您将不会收到错误。

创可贴修复:如果我不从 DTO 派生任何类并复制本应从 DTO 派生的所有类中的所有成员,那么一切都会按预期工作。但是为了维护起见,我宁愿使用继承。

我深入研究了 MS Odata 代码,但它很快变得毛茸茸,很难遵循流程,我无法弄清楚它应用于可查询的 lambda,以便在没有“魔法”的情况下尝试重现问题Web API 和 OData 修饰。

我在 SO 上发现了很多关于复合 DTO 的 Automapper 投影和 OData 的帖子,但没有一个看起来适用于这种情况。

如有任何帮助,我们将不胜感激。衷心感谢!

最佳答案

我已经为这个问题苦苦挣扎了几个小时 并归咎于 OData

首先,我在 here 中找到了解决方案解决方案是在模型构建器中调用Ignore 方法。

在您的情况下,在使用构建器配置 odata 时,添加

builder.Ignore<DeveloperDTO>(); //or whatever you don't want to map.

ODataConventionModelBuilder 遍历它找到的所有模型。并且 OData 以某种方式尝试将基类查询为派生类然后繁荣??(我认为)。

还找到了模型构建器的文档。 http://odata.github.io/WebApi/#02-04-convention-model-builder这可能会有用。

关于odata - 如果 DTO 具有派生类,则使用 OData 选择的 Automapper 投影会抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29223376/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com