【问题标题】:how to use an expression in a select clause如何在选择子句中使用表达式
【发布时间】:2018-05-14 21:50:24
【问题描述】:

考虑下面的伪代码

Expression<Func<E,Datetime?>> expr = 
    e => (e.d1 ?? e.Rel.d1) ?? e.d2;
var q = myContext.E_DbSet.Select(x => new someDeclaredType {
    Id = x.Id,
    V = expr
});

=> CS0029 无法将类型“System.Linq.Expressions.Expression>”隐式转换为“System.DateTime?”

如果我尝试编译

Expression<Func<E,Datetime?>> expr = 
    (e => (e.d1 ?? e.Rel.d1) ?? e.d2).Compile();
var q = myContext.E_DbSet.Select(x => new someDeclaredType {
    Id = x.Id,
    V = expr(x)
});

=> NotSupportedException:LINQ 表达式的节点类型“Invoke”在 LINQ to Entities 中不受支持。

我读过Invoke an Expression in a Select statement - LINQ to Entity Framework。但这不是我的确切情况。我需要在我的选择子句中包含一个现有的表达式。这个表达式是函数调用的结果。所以我必须在我的选择子句中使用expr

怎么做?

【问题讨论】:

    标签: c# entity-framework linq


    【解决方案1】:

    可能是这样的:

    Expression<Func<E,someDeclaredType>> expr = 
    e => new someDeclaredType() 
    {
        Id = e.Id, 
        V = (e.d1 ?? e.Rel.d1) ?? e.d2 
    };
    var q = myContext.E_DbSet.Select(expr);
    

    【讨论】:

    • 重点是(e.d1 ?? e.Rel.d1) ?? e.d2来自函数调用。
    • 有没有等效的查询语法?
    【解决方案2】:

    我终于找到了办法:

    Expression<Func<E,Datetime?>> expr = 
        e => (e.d1 ?? e.Rel.d1) ?? e.d2;
    Expression<Func<E,someDeclaredType>> sel = 
        x => new someDeclaredType {
            Id = x.Id,
            V = expr.Compile()(x)
        };
    var q = myContext.E_DbSet.Select(sel.Compile());
    

    另一种编码是(来自@Anthony):

    Expression<Func<E, someDeclaredType>> sel =
    e => new someDeclaredType()
    {
        Id = e.Id,
        V = expr.Compile()(e)
    };
    q = Files.Select(sel.Compile());
    

    按样本:dotnetfiddle

    请注意,该代码是为 linq to 实体设计的。由于Rel = null,它可能会在 linq 中引发异常来对象。

    【讨论】:

    • 只是-1,没有理由吗?请帮帮我
    • 我想我找出了 -1 的原因。看来compile的使用触发了完整的DbSet在内存中的加载。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 2023-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多