C# 使用razor组件上的动态列表在.net core 3.1上运行时BinderException
我正在使用带有EF和blazor的.NETCore3.1来尝试渲染一些razor组件。该场景是-我有大量可能的测试结果类型(所有这些类型都派生自基本测试结果类)。我正在为每种类型的测试结果创建一个razor组件,然后将从许多不同的主结果页(取决于父对象)调用该组件。下面的服务实现了单一类型的测试,所有这些都可以正常工作:C# 使用razor组件上的动态列表在.net core 3.1上运行时BinderException,c#,.net-core,entity-framework-core,razor-pages,blazor-server-side,C#,.net Core,Entity Framework Core,Razor Pages,Blazor Server Side,我正在使用带有EF和blazor的.NETCore3.1来尝试渲染一些razor组件。该场景是-我有大量可能的测试结果类型(所有这些类型都派生自基本测试结果类)。我正在为每种类型的测试结果创建一个razor组件,然后将从许多不同的主结果页(取决于父对象)调用该组件。下面的服务实现了单一类型的测试,所有这些都可以正常工作: public async Task<IList<TestRowWaterAbsorption>> GetTestList(string parentOb
public async Task<IList<TestRowWaterAbsorption>> GetTestList(string parentObject, int parentID)
{
var listDetails = new List<TestRowWaterAbsorption>();
switch (parentObject)
{
case "TestContainer":
listDetails = await _context.TestRowWaterAbsorption.Where(t=>t.TestContainerID == parentID).ToListAsync();
break;
case "TestRun":
listDetails = await _context.TestRowWaterAbsorption.Where(t => t.TestRunID == parentID).ToListAsync();
break;
case "Item":
listDetails = await _context.TestRowWaterAbsorption.Where(t => t.TestItemID == parentID).ToListAsync();
break;
default:
return listDetails = null;
}
return listDetails;
}
}
公共异步任务GetTestList(字符串parentObject,int parentID)
{
var listDetails=新列表();
开关(父对象)
{
案例“TestContainer”:
listDetails=wait_context.TestRowWaterAbsorption.Where(t=>t.TestContainerID==parentID).toListSync();
打破
案例“TestRun”:
listDetails=await_context.TestRowWaterAbsorption.Where(t=>t.TestRunID==parentID.toListSync();
打破
案例“项目”:
listDetails=await_context.TestRowWaterAbsorption.Where(t=>t.TestItemID==parentID.toListSync();
打破
违约:
返回listDetails=null;
}
返回列表详细信息;
}
}
然而,为每种可能的测试类型编写单独的方法似乎很可笑。我希望编写一个更通用的方法来实现上述逻辑(即选择适当的ID来查询数据库),并传入对象类型(在上面的示例中,这将是TestRowWaterAbsorption对象),然后选择适当的上下文并返回适当类型的列表
我尝试了以下方法,似乎返回了我想要的列表
:
public List<dynamic> GetListAsync(string parentObject, int parentID, string testObjectType)
{
var listDetails = new List<dynamic>();
IEnumerable listSet = _context.Set(Type.GetType(testObjectType));
switch (parentObject)
{
case "TestContainer":
//listDetails = await _context.TestRowWaterAbsorption.Where(t => t.TestContainerID == parentID).ToListAsync();
listDetails = ((IEnumerable)listSet).Cast<dynamic>().Where(t => t.TestContainerID == parentID).ToList();
break;
case "TestRun":
//listDetails = await _context.TestRowWaterAbsorption.Where(t => t.TestRunID == parentID).ToListAsync();
listDetails = ((IEnumerable)listSet).Cast<dynamic>().Where(t => t.TestRunID == parentID).ToList();
break;
case "Item":
//listDetails = await _context.TestRowWaterAbsorption.Where(t => t.TestItemID == parentID).ToListAsync();
//IQueryable<Object> listSet = _context.Set(Type.GetType(parentObject)).Where(t => t.TestItemID == parentID);
listDetails = ((IEnumerable)listSet).Cast<dynamic>().Where(t => t.TestItemID == parentID).ToList();
break;
default:
return listDetails;
}
return listDetails;
}
:
公共列表GetListAsync(字符串parentObject、int parentID、字符串testObjectType)
{
var listDetails=新列表();
IEnumerable listSet=_context.Set(Type.GetType(testObjectType));
开关(父对象)
{
案例“TestContainer”:
//listDetails=wait_context.TestRowWaterAbsorption.Where(t=>t.TestContainerID==parentID).toListSync();
listDetails=((IEnumerable)listSet.Cast()。其中(t=>t.TestContainerID==parentID).ToList();
打破
案例“TestRun”:
//listDetails=await_context.TestRowWaterAbsorption.Where(t=>t.TestRunID==parentID.toListSync();
listDetails=((IEnumerable)listSet.Cast()。其中(t=>t.TestRunID==parentID).ToList();
打破
案例“项目”:
//listDetails=await_context.TestRowWaterAbsorption.Where(t=>t.TestItemID==parentID.toListSync();
//IQueryable listSet=\u context.Set(Type.GetType(parentObject))。其中(t=>t.TestItemID==parentID);
listDetails=((IEnumerable)listSet.Cast()。其中(t=>t.TestItemID==parentID).ToList();
打破
违约:
返回列表详细信息;
}
返回列表详细信息;
}
需要使用以下扩展方法:
namespace Microsoft.EntityFrameworkCore
{
public static class DbContextExtensions
{
public static IQueryable<Object> Set(this DbContext _context, Type t)
{
return (IQueryable<Object>)_context.GetType().GetMethod("Set").MakeGenericMethod(t).Invoke(_context, null);
}
}
}
名称空间Microsoft.EntityFrameworkCore
{
公共静态类DbContextensions
{
公共静态IQueryable集(此DbContext _context,类型t)
{
return(IQueryable)_context.GetType().GetMethod(“Set”).MakeGenericMethod(t).Invoke(_context,null);
}
}
}
但是,当我尝试查看razor组件时,会出现以下错误
RuntimeBinderException:调用在以下两个方面不明确
方法或属性:
'Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(int,
字符串)和
'Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(int,
Microsoft.AspNetCore.Components.RenderFragment)'
查看debug中的对象似乎没有给我任何线索-列表似乎键入正确,并且具有预期的元素数
.razor文件如下所示,我在foreach语句后面的open{上得到未处理的异常
@using Microsoft.AspNetCore.Components.Web
@using KookaburraLab.Models
@using KookaburraLab.Services
@using System.Threading.Tasks
@inject ITestRowService testRowService
<h4>Testing generic method using generic option</h4>
<table class="table">
<thead>
<tr>
<th>
Status
</th>
<th>
Description
</th>
<th>
Initial Mass
</th>
<th>
Avg Thickness
</th>
<th>
Density
</th>
<th>
Initial Moisture
</th>
<th>
Mass after Soak
</th>
<th>
Water Absorption
</th>
<th>
Item ID
</th>
<th>
Sample ID
</th>
<th></th>
</tr>
</thead>
@if (testRowList == null)
{
<p><em>Loading...</em></p>
}
else
{
<tbody>
@foreach (var item in testRowList)
{
<tr>
<td>
@item.TestRowStatus
</td>
<td>
@item.TestRowSampleDescription
</td>
<td>
@item.InitialMass
</td>
<td>
@item.AverageThickness
</td>
<td>
@item.Density
</td>
<td>
@item.InitialMoisture
</td>
<td>
@item.MassAfterSoak
</td>
<td>
@item.WaterAbsorption
</td>
<td>
@item.TestItemID
</td>
<td>
@item.TestRowSampleID
</td>
<td>
</td>
</tr>
}
</tbody>
}
</table>
@code {
IEnumerable<dynamic> testRowList;
[Parameter]
public int parentID { get; set; }
[Parameter]
public string parentType { get; set; }
protected override async Task OnInitializedAsync()
{
testRowList = testRowService.GetListAsync(parentType,parentID,"KookaburraLab.Models.TestRowWaterAbsorption");
}
}
@使用Microsoft.AspNetCore.Components.Web
@使用笑翠鸟模型
@使用笑翠鸟服务
@使用System.Threading.Tasks
@注入ITestRowService testRowService
使用泛型选项测试泛型方法
地位
描述
初始质量
平均厚度
密度
初始湿度
浸泡后质量
吸水率
项目ID
样本ID
@if(testRowList==null)
{
加载
}
其他的
{
@foreach(testRowList中的var项)
{
@item.TestRowStatus
@item.TestRowSampleDescription
@项目.初始质量
@项目.平均厚度
@项目.密度
@项目.初始湿度
@第1项:浸泡