c# - Odata $expand 不适用于特定查询

标签 c# asp.net-core odata

我们正在为 Web 应用制作一个 ASP.NET Core API,该应用应使用 Entity Framework 从 SQL Server 数据库中获取用户列表(并扩展特定字段)。它一直有效,直到我们在 URL 中指定我们想要的用户 ID。

这是 Startup 类:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        private static IEdmModel GetEdmModel()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<User>("Users");
            builder.EntitySet<Character>("Characters");
            return builder.GetEdmModel();
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<GaiumContext>(opts => opts.UseSqlServer(Configuration["ConnectionString:Gaium"]));
            services.AddOData();
            services.AddMvc(options =>
            {
                options.EnableEndpointRouting = false;
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMvc(b =>
            {
                b.EnableDependencyInjection();
                b.Select().Expand().Filter().OrderBy().MaxTop(100).Count();
                b.MapODataServiceRoute("api", "api", GetEdmModel());
            });
        }
    }

这是 DbContext:

public class GaiumContext : DbContext
    {
        public GaiumContext(DbContextOptions<GaiumContext> options) : base(options)
        {
        }

        public DbSet<User> Users { get; set; }
        public DbSet<Character> Characters { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>().HasMany(c => c.Characters);
        }
    }

最后, Controller UsersController :

public class UsersController : ODataController
    {
        private GaiumContext _context;

        public UsersController(GaiumContext context)
        {
            _context = context;
        }

        [EnableQuery]
        public IActionResult Get()
        {
            return Ok(_context.Users);
        }

        [EnableQuery]
        public IActionResult Get(long key)
        {
            return Ok(_context.Users.Find(key));
        }
    }

用户对象如下所示:

Users {
  id: int,
  name: string,
  Characters: [{
    id: int,
    name: String
  }]
}

这是对所有用户的查询:

GET: https://localhost:44323/api/users?$expand=Characters

在这种情况下,查询工作正常,我们确实收到了用户列表以及他们的 Characters 字段。

{"@odata.context":"https://localhost:44323/api/$metadata#Users","value":[{"Id":1,"Username":"Ok","Characters":[{"Id":1,"Name":"bigusernamesmoke"}]}]}

但是当我们尝试使用他们的 ID 获取某个特定用户的结果时,Characters 列表是空的:

GET: https://localhost:44323/api/users/1?$expand=Characters
{"@odata.context":"https://localhost:44323/api/$metadata#Users/$entity","Id":1,"Username":"Ok","Characters":[]}

最佳答案

请注意,Find(key) 方法返回一个单个 Book 而不是一个可查询 对象:

return Ok(_context.Users.Find(key));

如果我更改您的代码以返回 SingleResult,如下所示:

[EnableQuery]
public SingleResult<User> Get(long key)
{
    var query = _context.Users.Where(p => p.Id == key);
    return SingleResult.Create(query);
}

它对我来说很好。

关于c# - Odata $expand 不适用于特定查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56012504/

相关文章:

c# - MVC 6 中的路由

angular - Azure Web App wwwroot 在发布时重复

c# - 如何声明自定义 oData 注释

c# - 如何从代码 (.xaml.cs) 打开 Material 设计对话框?

entity-framework - EFCore 1.1 Scaffold-DbContext 提供程序错误

c# - OData路由异常

android - 如何获取 OData v3 WCF 数据服务调用以使用 v3 协议(protocol)进行通信

c# - 使用 C# 测试 Ctrl 键是否按下

c# - .NET 部署 Office 2003 可再发行主互操作程序集 (o2003pia.msi)

c# - OrderBy 具有来自另一个表的值