如何解决ExplicitExpansion导致OData扩展无法正常工作
使用ExplicitExpansion()时,Odata扩展不起作用。 我的DTo和EF模型可以在下面的链接中找到。 Querying DTOs based on EF using Odata
我的Automapper类:
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<ClientRef,ClientContract>().
ForMember(dest => dest.ValidFrom,opt =>
{
opt.MapFrom(y => y.Clients.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).ValidFrom);
}).
ForMember(dest => dest.ValidTo,opt =>
{
opt.MapFrom(y => y.Clients.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).ValidTo);
}).
ForMember(dest => dest.FirstName,opt =>
{
opt.MapFrom(y => y.PhysicalPeople.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).FirstName);
}).
ForMember(dest => dest.LastName,opt =>
{
opt.MapFrom(y => y.PhysicalPeople.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).LastName);
}).
ForMember(dest => dest.BirthDate,opt =>
{
opt.MapFrom(y => y.PhysicalPeople.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).BirthDate);
}).
ForMember(dest => dest.FatherName,opt =>
{
opt.MapFrom(y => y.PhysicalPeople.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).FatherName);
}).
ForMember(dest => dest.CompanyName,opt =>
{
opt.MapFrom(y => y.Companies.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).CompanyName);
})
.
ForMember(dest => dest.PinNumber,opt =>
{
opt.MapFrom(y => y.PhysicalPeople.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).Pin);
}).
ForMember(dest => dest.Position,opt =>
{
opt.MapFrom(y => y.PhysicalPeople.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).Position);
}).
ForMember(dest => dest.PositionCustom,opt =>
{
opt.MapFrom(y => y.PhysicalPeople.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).PositionCustom);
}).
ForMember(dest => dest.ClientType,opt =>
{
opt.MapFrom(y => y.Clients.FirstOrDefault(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).ClientType);
})
.
ForMember(dest => dest.Documents,opt =>
{
opt.MapFrom(y => y.Documents.Where(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now));
//opt.ExplicitExpansion();
})
.ForMember(dest => dest.ContactsInfo,opt =>
{
opt.MapFrom(y => y.ClientContactInfoComps.Where(x => x.ValidFrom <= DateTime.Now && x.ValidTo > DateTime.Now).Select(x => x.ContactInfo));
//opt.ExplicitExpansion();
}).
ForMember(dest => dest.ClientComment,opt =>
{
opt.MapFrom(y => y.CommentComps.Where(x => x.Contact == null).Select(x => x.Comment));
//opt.ExplicitExpansion();
}).
ForMember(dest => dest.Relations,opt =>
{
opt.MapFrom(y => y.ClientRelationCompClient1Navigations);
//opt.ExplicitExpansion();
})
;
CreateMap<Document,DocumentContract>();
CreateMap<ContactInfo,ContactInfoContract>().
ForMember(dest => dest.ContactComments,opt =>
{
opt.MapFrom(y => y.CommentComps.Select(x => x.Comment));
});
CreateMap<ClientRelationComp,RelationContract>().
ForMember(dest => dest.ClientINN,opt => {
opt.MapFrom(x => x.Client2);
}).
ForMember(dest => dest.RelationType,opt => {
opt.MapFrom(x => x.RelationId);
});
CreateMap<ICollection<Client>,ClientContract>();
CreateMap<ICollection<PhysicalPerson>,ClientContract>();
CreateMap<ICollection<Company>,ClientContract>();
CreateMap<Comment,CommentContract>();
CreateMap<ICollection<Comment>,ICollection<ContactInfoContract>>();
CreateMap<ICollection<ClientRelationComp>,ClientRef>();
}
}
我的控制器:
public class ClientContractController : ODataController
{
CRMContext _context;
IMapper _mapper;
public ClientContractController(CRMContext ctx,IMapper mapper )
{
_context = ctx;
_mapper = mapper;
}
[EnableQuery(MaxExpansionDepth = 10)]
public IQueryable<ClientContract> Get()
{
return _mapper.ProjectTo<ClientContract>(_context.ClientRefs).Where(x => x.ValidFrom <= DateTime.Now && x.ValidTo >= DateTime.Now);
}
}
这给出了以下异常 https:// localhost:44371 / odata / clientcontract?$ expand = relations
System.InvalidOperationException:无法转换LINQ表达式'$ it'。以一种可以翻译的形式重写查询,或者通过插入对AsEnumerable(),AsAsyncEnumerable(),ToList()或ToListAsync()的调用来显式切换到客户端评估。有关更多信息,请参见https://go.microsoft.com/fwlink/?linkid=2101038。
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(表达式表达式)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)
在System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding节点)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
在System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor访问者)
在System.Linq.Expressions.ExpressionVisitor.Visit(Expression节点)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(表达式表达式)
在System.Linq.Expressions.ExpressionVisitor.VisitLambda [T](Expression 1 node) at System.Linq.Expressions.Expression
1.Accept(ExpressionVisitor访问者)处
在System.Linq.Expressions.ExpressionVisitor.Visit(Expression节点)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(表达式表达式)
在System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor访问者,IArgumentProvider节点)
在System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression节点)
在System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor访问者)
在System.Linq.Expressions.ExpressionVisitor.Visit(Expression节点)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(表达式表达式)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)
在System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding节点)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
在System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor访问者)
在System.Linq.Expressions.ExpressionVisitor.Visit(Expression节点)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(表达式表达式)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)
在System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding节点)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
在System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor访问者)
在System.Linq.Expressions.ExpressionVisitor.Visit(Expression节点)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(表达式表达式)
在Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression,表达式表达式)
在Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression源,LambdaExpression选择器)
在Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
在System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor访问者)
在System.Linq.Expressions.ExpressionVisitor.Visit(Expression节点)
在Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor [TResult](表达式查询)
在Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery [TResult](表达式查询,布尔异步)
在Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore [TResult](IDatabase数据库,表达式查询,IModel模型,布尔异步)
在Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler。 c__DisplayClass12_0 1.<ExecuteAsync>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey,Func
1编译器处)
在Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync [TResult](表达式查询,CancellationToken cancelledToken)
在Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync [TResult](表达式,CancellationToken cancelledToken)
在Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 1.GetAsyncEnumerator(CancellationToken cancellationToken) at Microsoft.AspNetCore.Mvc.Infrastructure.AsyncEnumerableReader.ReadInternal[T](Object value) at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncEnumerable(ActionContext context,ObjectResult result,Object asyncEnumerable,Func
2阅读器处)
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged | 21_0(ResourceInvoker调用程序,IActionResult结果)
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited | 29_0 [TFilter,TFilterAsync](ResourceInvoker调用程序,任务lastTask,状态下一个,作用域范围,对象状态,布尔值isCompleted)
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed上下文)
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext [TFilter,TFilterAsync](状态与下一个,范围与范围,对象与状态,布尔值和isCompleted)
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
---从之前引发异常的位置开始的堆栈结束跟踪---
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited | 19_0(ResourceInvoker调用程序,Task lastTask,Next状态,Scope作用域,对象状态,布尔值isCompleted)
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged | 17_1(ResourceInvoker调用程序)处
在Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask | 6_0(端点端点,任务requestTask,ILogger记录器)
在Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext上下文)
在Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext上下文)
解决方法
更新21/08/20202
没有explicit instructions,AutoMapper
将扩展结果中的所有成员。
要控制在投影过程中扩展哪些成员,请在配置中设置ExplicitExpansion
,然后传入要显式扩展的成员:
dbContext.Orders.ProjectTo<OrderDto>(configuration,dest => dest.Customer,dest => dest.LineItems);
// or string-based
dbContext.Orders.ProjectTo<OrderDto>(configuration,null,"Customer","LineItems");
// for collections
dbContext.Orders.ProjectTo<OrderDto>(configuration,dest => dest.LineItems.Select(item => item.Product));
使用OData
时使用属性名称,而不使用属性名称。
OData
客户端库依靠它自己的属性OriginalNameAttribute
来获得有关服务器发出的类/成员名的知识。您可以从here中看到详细信息。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。