.net 5 MVC,使用过滤列表过滤第二个列表

.net 5 MVC, Using a filtered list to filter the second list

我会先列出我的代码中的内容。

工单模型

public class WorkOrderModel
{
    public int RowID { get; set; }
    [Key]
    public string Type { get; set; } 
    [Key]
    public string Base_ID { get; set; }
    [Key]
    public string Lot_ID { get; set; }
    [Key]
    public string Split_ID { get; set; }
    [Key]
    public string Sub_ID { get; set; }

    #nullable enable
    public string? Part_ID { get; set; }
    [DataType(DataType.DateTime)]
    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? Close_Date { get; set; }
    public char Status { get; set; }
}

public class OperationModel
{
    [Key]
    public short Sequence_No { get; set; }
    public string Resource_Id { get; set; }

    [Column(TypeName = "decimal(7, 2)")]
    public decimal Run_Hrs { get; set; }

    [Column(TypeName = "decimal(7, 2)")]
    public decimal Act_Run_Hrs { get; set; }
    public string Operation_Type { get; set; }
    public char Status { get; set; }

    [DataType(DataType.DateTime)]
    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? Close_Date { get; set; }

    [Key]
    public string WorkOrder_Type { get; set; }
    [Key]
    public string WorkOrder_Base_ID { get; set; }
    [Key]
    public string WorkOrder_Lot_ID { get; set; }
    [Key]
    public string WorkOrder_Split_ID { get; set; }
    [Key]
    public string WorkOrder_Sub_ID { get; set; }
}

然后 WOListViewModel 结合以上两个(还有更多但尚未使用)

public class WoListViewModel
{
    public IQueryable<WorkOrderModel> WorkOrders { get; set; }
    public IQueryable<OperationModel> Operations { get; set; }
    public IQueryable<PartModel> Parts { get; set; }
    public IQueryable<LaborTicketModel> LaborTickets { get; set; }
}

和我的 WorkOrderController

public IActionResult Index(string woSearch = null, string tcSearch = null, string tdSearch = null)
{
        WoListViewModel woListViewModel = new()
        {
            WorkOrders = _dbContext.Work_Order.Where(w => w.Sub_ID != "0")
        };

        if (!string.IsNullOrEmpty(tdSearch))
        {
            woListViewModel.Operations = _dbContext.Operation.Where(o => o.Resource_Id == tdSearch);

            woListViewModel.WorkOrders = woListViewModel.WorkOrders.Where(w => (w.Base_ID + "-" + w.Sub_ID + "/" + w.Lot_ID) ==
                                            (from o in woListViewModel.Operations
                                             select  (o.WorkOrder_Base_ID + "-" + o.WorkOrder_Sub_ID + "/" + o.WorkOrder_Lot_ID)).ToQueryString()
                                             );
        }
}

我在 if (!string.IsNullOrEmpty(tdSearch)) 下的 IActionResult 中尝试做的是通过 tdSearch 过滤 woListViewModel.Operations。 然后用结果过滤woListViewModel.WorkOrders。 两种模型都有 Base_ID、Sub_ID、Lot_ID,在 SQL 服务器中很常见(虽然列名不准确,但它们是匹配数据),如果我要这样做Excel 中的两级过滤,我可以先在 PowerQuery 中合并两个表,然后过滤。

虽然我不知道我是否以某种方式正确地执行此操作,但我能够在 Visual Studio 中无错误地编写控制器代码,但是当它 运行 时产生了以下错误。

InvalidOperationException: The LINQ expression 'DbSet<OperationModel>()
.Where(o => o.Resource_Id == __tdSearch_0)
.Select(o => o.WorkOrder_Base_ID + "-" + o.WorkOrder_Sub_ID + "/" + o.WorkOrder_Lot_ID)
.ToQueryString()' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)

根据它的建议,我将 .ToQueryString() 更改为列出的其他人,但没有成功。

请帮帮我。 提前谢谢你。

Filter a list by another list C# 从上面的 link 中找到答案,然后如下更改我的代码。

woListViewModel.WorkOrders = woListViewModel.WorkOrders
                             .Where(w => woListViewModel.Operations
                                   .Any(o => (o.WorkOrder_Base_ID + "." + o.WorkOrder_Sub_ID + "." + o.WorkOrder_Lot_ID)
                                       .Equals(w.Base_ID + "." + w.Sub_ID + "." + w.Lot_ID)));