LinqKit 将变量传递到表达式中

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

我正在尝试将变量从外部上下文传递到使用 LinqKit 的表达式扩展构建的表达式中。

我遇到以下异常:

从范围“”引用的“System.String”类型的变量“__name_0”, 但它没有定义|System.InvalidOperationException:变量 从范围“”引用的“System.String”类型的“__name_0”,但它是 未定义。

public static class EntityProjections
{
    public static Expression<Func<Entity, Model>> GetModelProjection(string name)
    {
        return entity => new Model()
        {
            Id = entity.Id,
            Name = entity.Name != name ? entity.Name : null
        };
    }
}

string name = "Test";

var models = dbContext.Entities.Select(entity => EntityProjections.GetModelProjection(test).Invoke(entity)).ToList();

是否可以从外部传递这样的变量来构建所需的查询?

c# asp.net-core entity-framework-core expression linqkit
2个回答
1
投票

这里需要表达式替换。可以通过

ExpandableAttribute
来完成:

public static class EntityProjections
{
    [Expandable(nameof(GetModelProjectionImpl))]
    public static Model GetModelProjection(Entity entity, string name)
    {
        throw new NotImplementedException(); // should not call
    }

    // static function without parameters
    private static Expression<Func<Entity, string, Model>> GetModelProjectionImpl()
    {
        return (entity, name) => new Model()
        {
            Id = entity.Id,
            Name = entity.Name != name ? entity.Name : null
        };
    }
}

示例调用将是:

string name = "Test";

var models = dbContext.Entities
   .Select(entity => EntityProjections.GetModelProjection(entity, name))
   .ToList();

0
投票

虽然我很早之前就接受了答案,但我认为还有一个更简单的解决方案:

public static class EntityProjections
{
    public static Expression<Func<Entity, string, Model>> GetModelProjection()
    {
        return (entity, name) => new Model()
        {
            Id = entity.Id,
            Name = entity.Name != name ? entity.Name : null
        };
    }
}

string name = "Test";

var models = dbContext.Entities.Select(entity => EntityProjections.GetModelProjection().Invoke(entity, test)).ToList();

这样我们就不必替换表达式了。另外,我们还可以在 GetModelProjection(DbContext dbContext) 中传递 DbContext,调用 EntityProjections.GetModelProjection(dbContext).Invoke(...) 并在投影内进行子查询。这对于表达式替换来说是不可能的,因为 EF 无法翻译它。这就是为什么我更喜欢这个版本。

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