ExplicitExpansion()により、OData展開が機能しなくなります
ExplicitExpansion()を使用する場合、Odata展開は機能しません。私のDToモデルとEFモデルはリンクの下にあります。Odataを使用したEFに基づくDTOのクエリ
私のオートマッパークラス:
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)at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)at System.Linq.Expressions.ExpressionVisitor.Visitor Microsoft.EntityFrameworkのSystem.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)の.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression) System.Linq.Expressions.ExpressionVisitor.VisitLambda [T](Expression)での.Visit(Expression式)1 node) at System.Linq.Expressions.Expression
1.Accept(ExpressionVisitor visitor)at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor 、IArgumentProviderノード)at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)at Microsoft.EntityFrameworkCore .Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding( .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.Relation )Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBinding Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Express)のSystem.Linq.Expressions.ExpressionVisitor.Visit(Expressionノード)のLinq.Expressions.MemberInitExpression.Accept(ExpressionVisitorビジター)Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source、LambdaExpressionselector)のMicrosoft.EntityFrameworkCore.Query.QueryableMethodのMicrosoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression、Expression expression) 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 database、Expression query、IModel model、Boolean as ync)atMicrosoft.EntityFrameworkCore.Query.Internal.QueryCompiler。<> c__DisplayClass12_0 1.<ExecuteAsync>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func
1コンパイラ)at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync [TResult](Expression query、CancellationToken cancelToken)atMicrosoft.EntityFrameworkCore.Query.Internal 。 MicrosoftのEntityQueryProvider.ExecuteAsync [TResult](式、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)(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 2リーダー)(Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged | 21_0(ResourceInvoker呼び出し側、IActionResultの結果))。 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 )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__AwaitRequest | 6_0(エンドポイントエンドポイント、タスクrequestTask、ILoggerロガー)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
、サーバーがクラス/メンバー名を発行するときに、クラス/メンバー名に関する知識を得るためにそれ自体の属性に依存しています。あなたがここから見ることができる詳細。