c# - Odata $expand 不适用于特定查询
问题描述
我们正在为一个 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);
}
}
最后,控制器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
而不是可查询对象:
返回确定(_context.Users.Find(键));
如果我更改您的代码以返回SingleResult
如下:
[EnableQuery]
public SingleResult<User> Get(long key)
{
var query = _context.Users.Where(p => p.Id == key);
return SingleResult.Create(query);
}
这对我来说可以。