【问题标题】:How do I get Expression<System.Func<TEntity, TEntity>> when I have an Expression?当我有一个表达式时,如何获得 Expression<System.Func<TEntity, TEntity>>?
【发布时间】:2020-05-21 10:14:39
【问题描述】:

我正在研究服务的通用 PATCH 方法。

public virtual void Patch ( int id, Delta<TEntityView> view )
{
    var type = typeof( TEntity );
    TEntity model = Activator.CreateInstance( type ) as TEntity;

    foreach( var changedProperty in view.GetChangedPropertyNames() )
    {
        var property = type.GetProperty( changedProperty );
        var propertyType = property.PropertyType;
        var retreived = view.TryGetPropertyValue( changedProperty, out object propval );

        if ( retreived && property != null )
        {
            property.SetValue( model, propval, null );
        }
    }

    UnitOfWork.Query<TEntity>( e => e.Id == id )
        .Update( m => model );
}

Update 声明中,我得到了

System.Exception: 'Invalid Cast. The update expression must be of type MemberInitExpression.'

该方法在 Entity Framework Plus (https://entityframework-plus.net/) 中定义:

#region Assembly Z.EntityFramework.Plus.EF6, Version=1.12.14.0, Culture=neutral, PublicKeyToken=59b66d028979105b
public static int Update<T>(this IQueryable<T> query, Expression<Func<T, T>> updateFactory) where T : class;

我改变了我的方法如下:

public virtual void Patch ( int id, Delta<TEntityView> view )
{
    var type = typeof( TEntity );
    var bindings = new List<MemberBinding>();

    foreach( var changedProperty in view.GetChangedPropertyNames() )
    {
        var property = type.GetProperty( changedProperty );
        var propertyType = property.PropertyType;
        var retreived = view.TryGetPropertyValue( changedProperty, out object propval );

        if ( retreived && property != null )
        {
            bindings.Add( Expression.Bind( type.GetMember( changedProperty )[0], Expression.Constant( propval ) ) );
        }
    }

    Expression ex = Expression.MemberInit( Expression.New( type ), bindings );

    // Expression <-- have this
    // Expression<Func<TModel, TModel>> updateFactory <-- need this

    UnitOfWork.Query<TEntity>( e => e.Id == id )
        .Update( ex );
}

现在,在更新中,我收到一条带有红色波浪线的消息: Argument 1: cannot convert from 'System.Linq.Expressions.Expression' to 'System.Linq.Expressions.Expression&lt;System.Func&lt;TEntity, TEntity&gt;&gt;'

我确定我错过了一些小东西来使魔法发挥作用。这是什么?

【问题讨论】:

    标签: c# entity-framework generics expression-trees


    【解决方案1】:

    你做了最难的部分,乍一看它看起来是正确的,你想要的是将它包装在 lambda 中,这样部分就像 x => ex:

    var parameter = Expression.Parameter(type,"x");
    var lambda = Expression.Lambda<Func<TEntity,TEntity>>(ex, parameter);
    UnitOfWork.Query<TEntity>( e => e.Id == id )
        .Update( lambda );
    

    (凭记忆写,待验证)

    【讨论】:

    • 你的记忆力很好!它工作得很好。谢谢!我知道我错过了一些小东西:)
    猜你喜欢
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多