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

时间:2014-12-22 11:42:51

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

我的应用程序包含多种业务层类型。我使用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。

2 个答案:

答案 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">&times;</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();