在其他 linq 表达式中调用 linq 表达式

本文关键字:表达式 linq 调用 其他 | 更新日期: 2023-09-27 18:34:52

我的应用程序包含多种业务层类型。我使用 linq 表达式从实体框架实体创建它们。下面我放了应该描述我当前解决方案的示例代码。请考虑,这只是一个简单的示例。我的实际业务层类型要复杂得多。

public class SimpleType
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public static Expression<Func<simple_type_entity, SimpleType>> CreateExpression()
    {
        return arg => new SimpleType
        {
            Id = arg.id,
            Name = arg.name,
            Description = arg.desc
        }
    }
}
public class ComplexType
{
    public Guid Id { get; set; }
    public SimpleType Property1 { get; set; }
    public SimpleType Property2 { get; set; }
    public static Expression<Func<complex_type_entity, ComplexType>> CreateExpression()
    {
        return arg => new ComplexType
        {
            Id = arg.id,
            Property1 = new SimpleType 
            { 
                Id = arg.property1.id, 
                Name = arg.property1.name,   
                Description = arg.property1.desc
            },
            Property2 = new SimpleType { .... }
        }
    }
}

您可能会注意到,ComplexType多次创建SimpleType SimpleType并且创建代码是重复的。如何从另一个表达式调用 linq 表达式?我想在所有创建SimpleType的地方使用SimpleType.CreateExpression()。我使用 linq 表达式,因为据我所知,表达式被转换为 sql 查询,因此新的解决方案也应该转换为 sql 查询/与 linq 兼容。

在其他 linq 表达式中调用 linq 表达式

第一个版本在IQueryable上使用时不起作用。(仅在 IEnumerable 上(滚动到这篇文章中的最终版本以获得IQueryable工作版本。

public class ComplexType
{
    public Guid Id { get; set; }
    public SimpleType Property1 { get; set; }
    public SimpleType Property2 { get; set; }
    public static Expression<Func<complex_type_entity, ComplexType>> CreateExpression()
    {
        var compiledSimpleTypeFnc = SimpleType.CreateExpression().Compile();
        return arg => new ComplexType
        {
            Id = arg.id,
            Property1 = compiledSimpleTypeFnc(arg.property1),
            Property2 = compiledSimpleTypeFnc(arg.property2)
        };
    }
}

或者,如果您真的想将其作为表达式保留到最后:

public class ComplexType
{
    public Guid Id { get; set; }
    public SimpleType Property1 { get; set; }
    public SimpleType Property2 { get; set; }
    public static Expression<Func<complex_type_entity, ComplexType>> CreateExpression()
    {
        var expr = SimpleType.CreateExpression();
        return arg => new ComplexType
        {
            Id = arg.id,
            Property1 = expr.Compile()(arg.property1),
            Property2 = expr.Compile()(arg.property2)
        };
    }
}

编辑:以下代码适用于实体框架。

using System;
using System.Linq.Expressions;
using ConsoleApplication2;
using System.Linq;
class Program2
{
    public static void Main(string[] args)
    {
        using (var db = new TestEntities())
        {
            var exp = db.complex_type_entity.Select(ComplexType.CreateExpression()).First();
        }
    }
}
public class SimpleType
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public static Expression<Func<simple_type_entity, SimpleType>> CreateExpression()
    {
        var parameterExpr = Expression.Parameter(typeof(simple_type_entity), "p0");
        return Expression.Lambda<Func<simple_type_entity, SimpleType>>(CreateExpression(parameterExpr), parameterExpr);
    }
    public static MemberInitExpression CreateExpression(Expression sourceExpr)
    {
        return Expression.MemberInit(
            Expression.New(typeof(SimpleType)),
            Expression.Bind(typeof(SimpleType).GetProperty("Id"), Expression.Property(sourceExpr, "id")),
            Expression.Bind(typeof(SimpleType).GetProperty("Name"), Expression.Property(sourceExpr, "name")),
            Expression.Bind(typeof(SimpleType).GetProperty("Description"), Expression.Property(sourceExpr, "desc")));
    }
}
public class ComplexType
{
    public Guid Id { get; set; }
    public SimpleType Property1 { get; set; }
    public SimpleType Property2 { get; set; }
    public static Expression<Func<complex_type_entity, ComplexType>> CreateExpression()
    {
        var parameterExp = Expression.Parameter(typeof(complex_type_entity), "p0");
        return Expression.Lambda<Func<complex_type_entity, ComplexType>>(
            Expression.MemberInit(
                Expression.New(typeof(ComplexType)),
                Expression.Bind(typeof(ComplexType).GetProperty("Id"), Expression.Property(parameterExp, "id")),
                Expression.Bind(typeof(ComplexType).GetProperty("Property1"), SimpleType.CreateExpression(Expression.Property(parameterExp, "simple_type_entity"))),
                Expression.Bind(typeof(ComplexType).GetProperty("Property2"), SimpleType.CreateExpression(Expression.Property(parameterExp, "simple_type_entity1")))),
        parameterExp);
    }
}

我创建了这个存储库 https://github.com/jaider/Entity-Expressions,其中包含@TimEeckhaut EF解决方案,但更可重用/通用的库。

这里是数据库查询:

var complexModels = context.ComplexEntities
                .Select(EntityExpressionHelper.CreateLambda<ComplexEntity, ComplexModel>())
                .ToList();

这里的模型如下所示:

public class ComplexModel
{
    [EntityExpression(nameof(ComplexEntity.Id))]
    public Guid Id { get; set; }
    [EntityExpression(nameof(ComplexEntity.Property1), IsComplex = true)]
    public SimpleModel Property1 { get; set; }
    [EntityExpression(nameof(ComplexEntity.Property2), IsComplex = true)]
    public SimpleModel Property2 { get; set; }
}