我将Expression<T, bool>
转换为Expression<Y, bool>
其中T和Y是不同于除了通过自动映射器映射以外的任何方式相关的不同实体。从本质上讲,我有我的代码使用一个模型对象:表达式树空访问成员
public class Store
{
public string StoreId { get; set; }
public string Name { get; set; }
public List<Phone> Phones { get; set; }
public Address Address { get; set; }
public Account Account { get; set; }
public Status Status { get; set; }
}
,我映射到实体对象存储在我的Mongo的数据库:
public class Store : MongoEntity
{
public string AccountId { get; set; }
public string Name { get; set; }
public List<string> UserIds { get; set; }
public List<Phone> PhoneNumbers { get; set; }
public Address Address { get; set; }
}
public abstract class MongoEntity : IMongoEntity
{
[BsonId]
public ObjectId Id { get; set; }
public Status Status { get; set; }
}
我以前的答案在这个问题上的工作了解如何在表达式(Question)之间进行转换,并让我在那里获得了90%。我能够从源属性修改代码抢我的模型店,我店的实体之间的AutoMapper映射,抓住目标属性:
private Expression<Func<TNewTarget, bool>> TransformPredicateLambda<TOldTarget, TNewTarget>(
Expression<Func<TOldTarget, bool>> predicate)
{
var lambda = (LambdaExpression)predicate;
if (lambda == null)
{
throw new NotSupportedException();
}
//Modified here to get automapper mappings
var maps = Mapper.FindTypeMapFor<TOldTarget, TNewTarget>();
var mutator = new ExpressionTargetTypeMutator(t => typeof(TNewTarget), maps);
var explorer = new ExpressionTreeExplorer();
var converted = mutator.Visit(predicate.Body);
return Expression.Lambda<Func<TNewTarget, bool>>(
converted,
lambda.Name,
lambda.TailCall,
explorer.Explore(converted).OfType<ParameterExpression>());
}
protected override Expression VisitMember(MemberExpression node)
{
var dataContractType = node.Member.ReflectedType;
var activeRecordType = _typeConverter(dataContractType);
PropertyMap prop = null;
foreach (var propertyMap in _maps)
{
var source = propertyMap.SourceMember;
var dest = propertyMap.DestinationProperty;
if (source != null && source.Name == node.Member.Name)
{
prop = propertyMap;
}
}
if (prop == null)
{
return base.VisitMember(node);
}
var propertyName = prop.DestinationProperty.Name;
var property = activeRecordType.GetProperty(propertyName);
var converted = Expression.MakeMemberAccess(
base.Visit(node.Expression),
property
);
return converted;
}
的问题是,我的实体对象不具有所有与我的Model对象具有相同的属性(例如Account对象和AccountId)。当Transformer获得Model对象的Account属性时,我得到一个Exception(因为我的Entity对象没有匹配的属性)。我无法从VisitMember返回null,并且也不允许使用新的Expression()。我该如何处理忽略我的模型对象上不存在于我的实体对象上的属性?有信息更新,从评论
所以
,是一个更加清楚一点,我使用Automapper从Models.Store到Entity.Store映射。我的实体.Store只有一个AccountId(因为我不想复制所有帐户数据),但我的Models.Store需要整个帐户对象(我将通过查询Accounts集合来获取)。
Automapper基本上是将我的Account对象转换为我实体上的AccountId。因此,当我搜索x => x.Account.AccountId == abcd1234
(其中x是models.Store)时,我需要将我的表达式转换为x => x.AccountId == abcd1234
(其中x是一个Entity.Store)。
我有那部分工作(更换mS => mS.Account.AccountId == 1234
到mE => mE.AccountId == 1234
)。我现在遇到的问题是,在完成AccountId属性后,VisitMember将以Account作为节点进行调用。由于在我的Entity.Store对象中没有Account,所以我得到异常。
链接的问题是不能正常工作,我想这是[这一个](http://stackoverflow.com/questions/2797261/mutating-the-expression-tree-of-a-predicate-to-target-another-type)=) – 2015-02-07 21:27:01
对不起,大师,我更新了链接。 – Mike 2015-02-07 21:45:07
你会如何忽略“A”在谓词'x => x.A == 1'中不存在的事实? – usr 2015-02-07 22:06:58