我的应用程序包含多种业务层类型。我使用linq表达式从Entity Framework实体创建它们。下面我给出了应该描述我当前解决方案的示例代码。请考虑一下,这只是一个简单的例子。我真正的业务层类型要复杂得多。
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.CreateExpression()
的所有地方使用SimpleType
。我使用linq表达式,因为据我所知,表达式被转换为sql查询,所以新的解决方案也应该转换为sql查询/兼容linq to entieties。
答案 0 :(得分:2)
在IQueryable上使用时,第一个版本不起作用。 (仅限IEnumerable) 滚动到这篇文章中的最终版本以获得IQueryable-working版本。
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);
}
}
答案 1 :(得分:1)
我创建了这个包含@TimEeckhaut EF解决方案的存储库https://github.com/jaider/Entity-Expressions,但是更多的可重用/通用库。
这里是数据库查询:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body" data-toggle="tooltip" data-placement="bottom" title="Tooltip on bottom">
<label id="lblWTooltip">Hello World</label>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
这里的模型如下:
var complexModels = context.ComplexEntities
.Select(EntityExpressionHelper.CreateLambda<ComplexEntity, ComplexModel>())
.ToList();