通常使用LINQ select忽略字段

问题描述 投票:0回答:1

我无法找到任何示例,可以在LINQ的选择投影中根据变量有条件地排除字段,请参见LINQ: Select an object and change some properties without creating a new object

让我为我要实现的目标提供一些背景知识。我想根据用户是否可以编辑数据来限制从模型设置的DTO中的某些字段(即注释字段)。例如,以下选择了一个名为CustomerView的委托。

var qry = _ctx.Customer.Select(CustomerView(User.IsInRole("Editor")));

Customer模型具有Orders导航属性,并且以下函数将数据转换为CusomerViewModel DTO。

private Expression<Func<Customer, CustomerViewModel>> CustomerView(bool isEditor) {
    return c => new CustomerViewModel
    {
        Id = c.Id,
        Name = c.Name,
        Comment = isEditor ? c.Comment : null,
        OrderCount = c.Orders.Count()
    };
}

这将生成像CASE WHEN @__isEditor_0 = TRUE THEN Comment ELSE NULL一样有效的SQL,但我希望甚至不生成该表达式,即默认保留字段。这是一个简单的用例,但是如果我想对OrderCount字段执行相同的操作,则仍将包含SQL子查询。

当然,我可以为非编辑者用户创建另一个函数,该函数排除某些字段,但是我宁愿没有单独的投影来维护,尤其是当它们更复杂时。

我看到问题,其中动态LINQ用于where子句,但对于select子句却不多。这种方法可行吗?

Edit:在使用了选择之后,是否可以通过扩展方法手动从表达式树中删除字段?

linq entity-framework-core expression-trees dynamic-linq linqkit
1个回答
0
投票

使用LINQKit,我可以通过添加AsExpandable()进行选择来达到所需的结果。

var qry = _ctx.Customer.AsExpandable().Select(CustomerView(User.IsInRole("Editor")));

然后为注释字段添加表达式,并在字段分配上调用Invoke()

private Expression<Func<Customer, CustomerViewModel>> CustomerView(bool isEditor) {
    Expression<Func<Customer, string>> exprComment;
    if (isEditor)
        exprComment = c => c.Comment;
    else
        exprComment = c => null;

    return c => new CustomerViewModel
    {
        Id = c.Id,
        Name = c.Name,
        Comment = exprComment.Invoke(c),
        OrderCount = c.Orders.Count()
    };
}

它似乎确实有效,但是我仍然想听听其他方法。

© www.soinside.com 2019 - 2024. All rights reserved.