【问题标题】:How to define expression selection nested one-to-one relationship in Entity Framework如何在实体框架中定义表达式选择嵌套的一对一关系
【发布时间】:2015-04-30 06:39:54
【问题描述】:

我正在尝试将包含此 Expression 的 Linq-to-Entity 运行到实体框架中。

不工作:

//2 seperated expressions, 1st expression calling the 2nd expression
public Expression<Func<User, UserDto>> UserToDtoExpr() {
    var expr = AddressToDtoExpr();
    return x => new UserDto() {
        Id = x.Id,
        Name = x.Name,
        Address = expr.Compile()(x.Address)
    };  
}
public Expression<Func<Address, AddressDto>> AddressToDtoExpr() {
    return x => New AddressDto() {
        Id = x.Id,
        City = x.City,
        Country= x.Country
    };
}

异常The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.

现在,我如果硬编码并将其嵌套到一个 Expression 中,然后将其放入 Linq-to-Entity 中,那么它就可以工作了:

//hardcode combined together into 1 expression with nested object
public static Expression<Func<User, UserDto>> UserToDtoExpr() {
    return x => new UserDto() {
        Id = x.Id,
        Name = x.Name,
        Address = New AddressDto() {
            Id = x.Address.Id,
            City= x.Address.City,
            Country = x.Address.Country
        }
    };  
}

但我不想像第二种方式那样对其进行硬编码,因为我想模块化和重用这些Expression 函数。如何修复第一种使其工作的方法?谢谢。

【问题讨论】:

    标签: c# entity-framework linq-to-entities


    【解决方案1】:

    你需要使用LinqKitAsExpandable()来实现这个。

    首先,将你的表达式改为使用LinqKit的Invoke()(扩展方法)如下:

    Address = expr.Invoke(x.Address) // instead of expr.Compile()(x.Address)
    

    然后在您的DbSet&lt;T&gt; 上使用AsExpandable()

    var results = context.Users.AsExpandable().Select(UserToDtoExpr());
    

    阅读this 了解嵌套表达式的问题。

    【讨论】:

    • 不使用LinqKit很难实现这种结构吗?
    • expr.Compile() 返回一个Func&lt;Address, AddressDto&gt;,EF 无法将其转换为 SQL。 必须采取一些措施 来克服这个问题,LinqKit 优雅而高效地做到了。如果您不喜欢引入新代码并且不自己编写解决方法的想法,我认为您必须使用常规 Lambda 构建您的表达式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多