在其他 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 兼容。
第一个版本在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; }
}