public Expression <Func <T, T> > Build <T>(ExpressionResultSet result, AffectableEntityInfoCache cache) { var parameter = Expression.Parameter(cache.Type, "dataSet"); var newParameter = Expression.Parameter(cache.Type, "newDataSet"); var assign = Expression.Assign(newParameter, Expression.New(parameter.Type)); var label = Expression.Label(newParameter.Type, "returnEntity"); var nonAffectedProperties = cache.NonAffectablePropertyInfos.Concat( cache.AffectablePropertyInfos.Select( _ => new KeyValuePair <string, PropertyInfo>(_.Key, _.Value.PropertyInfo))) .ToDictionary(_ => _.Key, _ => _.Value); var expr = new List <Expression> { assign }; foreach (var group in result.ExpressionResults.GroupBy(_ => _.TargetPropertyInfo.Name)) { var info = cache.AffectableEntityInfo(group.Key); expr.Add(BuildMain(group.Select(_ => _).ToArray(), result.Parameters, info, parameter, newParameter)); nonAffectedProperties.Remove(info.PropertyName); } expr.AddRange(AssignOnlyExpression(parameter, newParameter, nonAffectedProperties.Values)); expr.Add(Expression.Return(label, newParameter, newParameter.Type)); expr.Add(Expression.Label(label, Expression.Constant(null, newParameter.Type))); var block = Expression.Block(newParameter.Type, new[] { newParameter }, expr); var lambda = Expression.Lambda <Func <T, T> >(block, new[] { parameter }); return(lambda); }
private static AffectableEntityInfoContainer GetContainer(Type type) { AffectableEntityInfoContainer container; if (!Cache.TryGetValue(type, out container)) { var cache = new AffectableEntityInfoCache(type); container = new AffectableEntityInfoContainer(cache); Cache[type] = container; } return(container); }
public ParameterCache(AffectableEntityInfoCache cache) { _cache = cache; }
public AffectableEntityInfoContainer(AffectableEntityInfoCache cache) { EntityInfoCache = cache; ParameterCache = new ParameterCache(cache); }