当我有一个表达式时,如何获得 Expression<System.Func<TEntity, TEntity>>?
How do I get Expression<System.Func<TEntity, TEntity>> when I have an Expression?
我正在研究服务的通用 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<System.Func<TEntity, TEntity>>'
我确信我遗漏了一些小东西来让魔法发挥作用。这是什么?
你完成了困难的部分,乍一看它看起来是正确的,你想要的是用 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 );
(凭记忆写的待验证)
我正在研究服务的通用 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<System.Func<TEntity, TEntity>>'
我确信我遗漏了一些小东西来让魔法发挥作用。这是什么?
你完成了困难的部分,乍一看它看起来是正确的,你想要的是用 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 );
(凭记忆写的待验证)