实体类型无法配置为复杂类型,因为派生类型已配置为实体类型。 ODataConventionModelBuilder GetEdmModel

问题描述 投票:0回答:1

背景:我们将此代码与以前版本的 OData v4.0.30319 和 .net 4.8 一起使用,它工作正常,最近我们开始将项目迁移到 .NET Core 6 并使用 Microsoft.AspNetCore.OData 8.2.3 和 Microsoft.Data .OData 5.8.5

我在尝试在以下代码中调用 GetEdmModel 时遇到错误

        private static ODataQueryOptions CreateDynamicQueryOptions(ODataQueryOptions<DynamicPoco> originalQuery, Type entityType)
        {
            var entityClrType = entityType;
            var builder = new ODataConventionModelBuilder();
            var entityTypeConfiguration = builder.AddEntityType(entityClrType);

            var entitySetConfiguration = builder.AddEntitySet(entityClrType.Name, entityTypeConfiguration);
            
            var edmModel = builder.GetEdmModel();
            var queryContext = new ODataQueryContext(edmModel, entityClrType, originalQuery.Context.Path);

            return new ODataQueryOptions(queryContext, originalQuery.Request);
        }

出现此错误

System.InvalidOperationException:实体类型“System.Attribute”无法配置为复杂类型,因为派生类型“Newtonsoft.Json.JsonContainerAttribute”已配置为实体类型。 在 Microsoft.OData.ModelBuilder.ODataConventionModelBuilder.ReconfigureEntityTypesAsComplexType(EntityTypeConfiguration[] 错误配置的EntityTypes) 在 Microsoft.OData.ModelBuilder.ODataConventionModelBuilder.RediscoverComplexTypes() 在 Microsoft.OData.ModelBuilder.ODataConventionModelBuilder.GetEdmModel() 在项目相关电话会议上 在 lambda_method5( 闭包 , 对象 , 对象[] ) 在 Microsoft.AspNetCore.Mvc.Infrastruct.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper 映射器、ObjectMethodExecutor 执行器、对象控制器、Object[] 参数) 在 Microsoft.AspNetCore.Mvc.Infrastruct.ControllerActionInvoker.g__Logged|12_1(ControllerActionInvoker 调用程序) 在 Microsoft.AspNetCore.Mvc.Infrastruct.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker 调用程序、任务lastTask、状态下一个、范围范围、对象状态、布尔值已完成) 在 Microsoft.AspNetCore.Mvc.Infrastruct.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed 上下文) 在 Microsoft.AspNetCore.Mvc.Infrastruct.ControllerActionInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastruct.ControllerActionInvoker.InvokeInnerFilterAsync() --- 先前位置的堆栈跟踪结束 --- 在 Microsoft.AspNetCore.Mvc.Infrastruct.ResourceInvoker.g__Awaited|25_0(ResourceInvoker 调用程序、任务lastTask、状态下一个、范围范围、对象状态、布尔值已完成) 在 Microsoft.AspNetCore.Mvc.Infrastruct.ResourceInvoker.Rethrow(ResourceExecutedContextSealed 上下文) 在 Microsoft.AspNetCore.Mvc.Infrastruct.ResourceInvoker.Next(状态与下一个、范围与范围、对象与状态、布尔值与已完成) 在 Microsoft.AspNetCore.Mvc.Infrastruct.ResourceInvoker.InvokeFilterPipelineAsync() --- 先前位置的堆栈跟踪结束 --- 在 Microsoft.AspNetCore.Mvc.Infrastruct.ResourceInvoker.g__Logged|17_1(ResourceInvoker 调用程序) 在 Microsoft.AspNetCore.Mvc.Infrastruct.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 上下文)

执行此行时

var edmModel = builder.GetEdmModel();

如果有人让我知道我在这里做错了什么或者如何纠正它,那将会有很大的帮助

这就是我正在通过的类型

public class ErpLicenseViewModel : IErpLicenseModel
{
    public string Code { get; set; }
    public Guid LicenseGuid { get; set; }
    public DateTime ExpiryDate { get; set; }
    public int Count { get; set; }
    public bool Disabled { get; set; }
}
c# asp.net-core odata
1个回答
0
投票

我已经解决了这个问题,愚蠢的我应该先在之前的代码文件中看到它。

在之前的代码文件中,它与一些构造函数参数一起使用。

var builder = new ODataConventionModelBuilder(GlobalConfiguration.Configuration, true);

在迁移过程中,由于编译错误,我已经更新了它,不带任何参数调用它。这是我的一位前辈向我展示的,我是这样解决的。

使用带参数的构造函数:

var builder = new 
    ODataConventionModelBuilder(DefaultAssemblyResolver.Default, true);
    

默认AssemblyResolver:

public class DefaultAssemblyResolver : IAssemblyResolver
{
    private Assembly[] _assemblies = GetAssembliesInteral();

    /// <summary>
    /// This static instance is used in the shared code in places where the request container context
    /// is not known or does not contain an instance of IWebApiAssembliesResolver.
    /// </summary>
    internal static IAssemblyResolver Default = new DefaultAssemblyResolver();

    /// <summary>
    /// Gets the assemblies.
    /// </summary>
    public IEnumerable<Assembly> Assemblies => _assemblies;

    private static Assembly[] GetAssembliesInteral()
    {
        return AppDomain.CurrentDomain.GetAssemblies();
    }
}

感谢所有试图帮助我的人。

© www.soinside.com 2019 - 2024. All rights reserved.