ExplicitExpansion ()으로 인해 OData 확장이 작동하지 않습니다.
ExplicitExpansion ()을 사용할 때 Odata 확장이 작동하지 않습니다. 내 DTo 및 EF 모델은 링크 아래에서 찾을 수 있습니다. Odata를 사용하여 EF 기반 DTO 쿼리
내 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 (Expression expression)의 Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment (MemberAssignment memberAssignment)의 System.Linq.Expression.ExpressionVisitor.Core. .Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberInit (MemberInitExpression memberInitExpression) at System.Linq.Expressions.MemberInitExpression.Accept (ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit (Expression node) at Microsoft.EntityFrameworkCore.Expression System.Linq.Expressions.ExpressionVisitor.VisitLambda [T] (Expression에서 .Visit (Expression expression)1 node) at System.Linq.Expressions.Expression
1. Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit (Expression expression)의 System.Linq.Expressions.ExpressionVisitor.Visit (Expression node)에서 System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments (ExpressionVisitor 방문자)를 수락 (ExpressionVisitor 방문자) , IArgumentProvider 노드)의 System.Linq.Expressions.ExpressionVisitor.VisitMethodCall (MethodCallExpression node)의 System.Linq.Expressions.MethodCallExpression.Accept (ExpressionVisitor 방문자)의 System.Linq.Expressions.ExpressionVisitor.Visit (Expression node)의 Microsoft.Entity .Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit (Expression expression) at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment (MemberAssignment memberAssignment) at System.Linq.Expressions.ExpressionVisitor.Visit.InternalBinding (MemberBinding node) at Microsoft.EntityFrameworkCore. .RelationalProjecti onBindingExpressionVisitor.VisitMemberInit (MemberInitExpression memberInitExpression) at System.Linq.Expressions.MemberInitExpression.Accept (ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit (Expression node) at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpression ) at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment (MemberAssignment memberAssignment) at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding (MemberBinding node) at Microsoft.EntityFrameworkCore.Member.Internal.RelationalInternal.Visit Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit (Express ion expression) at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Translate (SelectExpression selectExpression, Expression expression) at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelect (ShapedQueryTransion source, LambdaExpressionlatingion) at Microsoft.Entity.FrameworkCore.Method.Queryable MethodCallExpression methodCallExpression) at System.Linq.Expressions.MethodCallExpression.Accept (ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit (Expression node) at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor [TResult] (Expression query) at Microsoft .EntityFrameworkCore.Storage.Database.CompileQuery [TResult] (Expression query, Boolean async) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore [TResult] (IDatabase 데이터베이스, 식 쿼리, IModel 모델, Boolean as ync) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler. <> c__DisplayClass12_0 1.<ExecuteAsync>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func
1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync [TResult] (Expression query, CancellationToken cancelToken ) at Microsoft.EntityFrameworkCore.Query.Internal. EntityQueryProvider.ExecuteAsync [TResult] (Expression expression, CancellationToken 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
cancelToken ) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 2 reader) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged | 21_0 (ResourceInvoker invoker, IActionResult result) at Microsoft. AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited | 29_0 [TFilter, TFilterAsync] (ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow (ResultExecutedContextSealed context ) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext [TFilter, TFilterAsync] (State & next, Scope & sc ope, Object & state, Boolean & isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters () --- 예외가 발생한 이전 위치의 스택 추적 끝 --- Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker. g__Awaited | 19_0 (ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged | 17_1 (ResourceInvoker invoker) at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask | 6_0 (Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke (HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke (HttpContext context)
답변
업데이트 21/08/20202
없이 명시 적 지시 , 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,
null,
dest => dest.LineItems.Select(item => item.Product));
를 사용할 때는 속성 이름이 아니라 속성 이름을 사용하십시오 OData
.
OData
클라이언트 라이브러리 OriginalNameAttribute
는 서버가 클래스 / 멤버 이름을 내보낼 때 클래스 / 멤버 이름에 대한 지식을 얻기 위해 자체 속성에 의존 합니다. 여기 에서 볼 수있는 세부 사항 입니다.