Net Core:在洋葱架构中使用OData,将查询参数转换为Linq
Posted
技术标签:
【中文标题】Net Core:在洋葱架构中使用OData,将查询参数转换为Linq【英文标题】:Net Core: Using OData in Onion Architecture, Convert Query Parameters Into Linq 【发布时间】:2020-10-20 08:10:07 【问题描述】:我们正在创建一个搜索函数来返回大型数据库中的匹配地址记录。
地址表包含 SQL 表中的 20+ 列,需要使用不同的 OData 参数(EqualTo、Contains、Starts With 等)进行查询。
尝试使用 OData,而不将 DBContext 注入 API 控制器。这在当前架构中是不允许的。如何编写代码来实现这一点?
*我们使用 ProjectTo 让它工作。但是,OData Http 特定功能正在传递到非 Api 级别。 目前在 AppServices 中有 ODataQueryOptions。
我们如何将 Whole ODataQueryOptions 转换为 Linq 表达式查询(不管传入什么),这个资源只用于过滤器,How to transform OData filter to a LINQ expression?
DBContext-->DomainLayer-->Dto--> 然后是API Level,
两个中间层。映射器从 EF DBContext 映射到 Domain 到 Dto。
存储库方法带来数据。
AppService 方法转换为 Dto。
ProjectTo 的当前解决方案:
控制器 API:
[HttpGet]
public async Task<ActionResult<IList<AddressTypeDto>> GetAddressAPI(ODataQueryOptions<AddressTypeDto> queryOptions)
return Ok(await _service.GetAddressTypeDto(queryOptions));
应用服务:
(我们如何在 Startup 中应用 ODataModelBuilder 映射?)
public async Task<AddressTypeResponse> GetAddressTypeDto(ODataQueryOptions<AddressTypeDto> queryOptions)
var dto = (IQueryable<AddressTypeDto>)queryOptions.ApplyTo(_addressRepository.GetAddressTypes().ProjectTo<AddressTypeDto>(_mapper.ConfigurationProvider));
var dtoList = await dto.ToListAsync();
return dto;
存储库:
[EnableQuery]
public IQueryable<LkAddressType> GetAddressTypesData()
return _ctx.LkAddressType.AsNoTracking();
类:
public class AddressTypeDto
public int AddressTypeId get; set;
public int? LastModifiedByUserId get; set;
public string AddressTypeCode get; set;
public string AddressTypeDescription get; set;
public bool? Status get; set;
public DateTime? CreateDate get; set;
public LkAddressType()
public int LkAddressTypeId get; set;
public int? LastModifiedByUserId get; set;
public string AddressTypeCode get; set;
public string AddressTypeDescription get; set;
public bool? Status get; set;
public DateTime? CreateDate get; set;
public DateTime? EffectiveStartDate get; set;
public DateTime? EffectiveEndDate get; set;
使用 C# Net Core 2.2、Entity Framework、Sql Server 数据库
资源: 也尝试使用它
How do I map an OData query against a DTO to another entity?
【问题讨论】:
我认为[Queryable]
属性仅适用于IQueryable
的结果函数。当您调用ToListAsync
时,查询实际上是对数据库执行的。更改您的代码以返回 db.AddressData
嗨@Max 好的,我如何将参数传递到可查询的存储库中?随意写完整的答案,我可以发送积分,谢谢
【参考方案1】:
我写这个函数已经很久了,但链接可能会有所帮助。 GetAll() 只返回一个 IEnumerable。
[Route(""), HttpGet]
public IHttpActionResult Get(ODataQueryOptions<Language> queryOptions)
Log.Info($"nameof(Get) (ODataQueryOptions)");
//OData directly with normal WebAPI
//https://blogs.msdn.microsoft.com/webdev/2013/02/25/translating-odata-queries-to-hql/
//https://***.com/questions/10781309/asp-net-mvc-4-webapi-manually-handle-odata-queries
//https://blogs.msdn.microsoft.com/odatateam/2014/07/04/tutorial-sample-using-odatauriparser-for-odata-v4/
//OData without entity framework, but full-on odata controller
//http://www.odata.org/blog/how-to-use-web-api-odata-to-build-an-odata-v4-service-without-entity-framework/
//OData tips and tricks
//https://blogs.msdn.microsoft.com/davidhardin/2014/12/17/web-api-odata-v4-lessons-learned/
return Ok(queryOptions.ApplyTo(_repository.GetAll().AsQueryable()));
【讨论】:
嗨 @Remy,我正在寻找 linq 中的表达式树,更多 iqueryable 部分,我已经在代码中有 Applyto以上是关于Net Core:在洋葱架构中使用OData,将查询参数转换为Linq的主要内容,如果未能解决你的问题,请参考以下文章
在 .NET Core Web API for MongoDB 中使用 OData
如何正确地将 OData 与 ASP.net Core 集成
使用 ASP.NET Core OData 8.0 映射动态 OData 路由
.Net Core 上的 OData 不会在 $select 上返回正确的结果