首页 > 解决方案 > 是否可以基于 OData 查询呈现视图?

问题描述

我有 Asp.Net Core 应用程序,并且有一个抽象控制器。

我想创建一个方法,它允许我将实体列表呈现为 PartialView。

我做了这样的:

应该返回带有实体列表的 PartialView

[HttpGet]
[EnableQuery()]
public async Task<IActionResult> _List()
{
    var result = _context.GetQueryByType<T>(); //returns DbSet<T> of whole table
    return PartialView(await result.ToListAsync());
}

示例部分视图

@model IEnumerable<SomeClass>

<table class="table table-sm table-striped table-hover">
...
</table>

我想这样调用我的方法:

http://localhost:32769/SomeController/_List?$filter=id%20eq%2009515a38-2a1a-4a53-a4f8-e91e4dbd870b

并获得过滤的列表视图。

但无论如何我只得到整个表数据。

对我来说唯一的解决方案是将这个逻辑分成两种方法:

  1. 通过标准 Odata 方法获取过滤后的 Json 数据,例如:

http://localhost:32769/odata/SomeClass?$filter=ReleaseId%20eq%2011f28258-48cb-4c82-85e0-822850fd1f5c

  1. 将此数据传递给方法:
[HttpPost]
public IActionResult _List([FromBody] IEnumerable<T> entities)
{
    return PartialView(entities);
}

我不喜欢这个解决方案。是否有可能使用 OData 查询过滤我的视图数据?

标签: asp.net-coreodata

解决方案


感谢 ChristophLütjen。

.ApplyTo() 是解决方案。

最后,工作方法如下:

[HttpGet]
[EnableQuery]
public async Task<IActionResult> _List(ODataQueryOptions<T> queryOptions)
{
    var result= (IQueryable<T>)queryOptions.ApplyTo(_context.GetQueryByType<T>());
    return PartialView(await result.ToListAsync());
}

此外,使用非常重要ODataQueryOptions<T>,而不是ODataQueryOptions.

如果你将使用非公共类,你会得到一个错误,该方法应该返回IEnumerable<T>,但不是IActionResult

这是一些文档。只是想把它固定在答案上。

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnet.odata.query.odataqueryoptions?view=odata-aspnetcore-7.0

希望这些信息对其他人有用。

更新:

我还发现,如果您想$expand在 OData 查询中使用方法,这不是完美的解决方案。

如果您尝试获取T扩展查询的类型,您将面临 SelectAllAndExpand 类型的问题。

在这种情况下,这是解决方案,我认为它不是很漂亮和完美,但它有效:

[HttpGet]
[EnableQuery]
public IActionResult _List(ODataQueryOptions<T> queryOptions)
{
    var validationSettings = new ODataValidationSettings
    {
        AllowedQueryOptions = AllowedQueryOptions.All,
        AllowedFunctions = AllowedFunctions.All,
    };

    queryOptions.Validate(validationSettings);
    IQueryable resultSet = queryOptions.ApplyTo(_context.GetQueryByType<T>(), new ODataQuerySettings());

    List<T> resultList = new List<T>();

    foreach (var item in resultSet)
    {
        if (item is T)
        {
            resultList.Add((T)item);
        }
        else if (item.GetType().Name == "SelectAllAndExpand`1")
        {
            var entityProperty = item.GetType().GetProperty("Instance");
            resultList.Add((T)entityProperty.GetValue(item));
        }
    }

    return PartialView(resultList as IEnumerable<T>);
}

在这里找到它:https ://github.com/OData/WebApi/issues/1441


推荐阅读