public static IDbSelect Map( IDbSelect dbSelect, Type returnType, IModelInfoProvider infoProvider, IDbObjectFactory dbFactory, UniqueNameGenerator nameGenerator) { // If the select returns specified columns, it means there is a constructor in Select, // e.g (.Select(d => new { A = d.ABC })) // In this case we do not need to add alias to the end result as where will be one in the select if (dbSelect.Selection.Any(s => !(s is IDbRefColumn))) { return(dbSelect); } var entityInfo = infoProvider.FindEntityInfo(returnType); if (!entityInfo.RequirePropertyNameMapping()) { return(dbSelect); } var alias = nameGenerator.GenerateAlias(dbSelect, TranslationConstants.SubSelectPrefix, true); var newSelectRef = dbFactory.BuildRef(dbSelect, alias); var newSelect = dbFactory.BuildSelect(newSelectRef); foreach (var fieldInfo in entityInfo.Columns) { var column = dbFactory.BuildColumn( newSelectRef, fieldInfo.DbName, fieldInfo.ValType, fieldInfo.PropertyName); newSelect.Selection.Add(column); } return(newSelect); }
protected override Expression VisitConstant(ConstantExpression c) { var entityInfo = _infoProvider.FindEntityInfo(c.Type); if (entityInfo != null) { var dbTable = _dbFactory.BuildTable(entityInfo); var dbRef = _dbFactory.BuildRef(dbTable); var dbSelect = _dbFactory.BuildSelect(dbRef); dbRef.Alias = _nameGenerator.GenerateAlias(dbSelect, dbTable.TableName); _state.ResultStack.Push(dbSelect); } else if (!c.Type.IsAnonymouse()) { var dbConstant = _dbFactory.BuildConstant(c.Value, true); _state.ResultStack.Push(dbConstant); } return(c); }
public static LambdaExpression Make(MemberExpression memberExpr, IModelInfoProvider infoProvider) { /** for example * relation: b => b.posts * fill func: * Action<IEnumerable<Blog>, IEnumerable<Post>> x = (bs, ps) => * { * var dict = ps.GroupBy(p => p.BlogId).ToDictionary(g => g.Key); * foreach (var blog in bs) * { * if (dict.ContainsKey(blog.BlogId)) * { * var posts = dict[blog.BlogId]; * blog.Posts.AddRange(posts); * * foreach (var post in posts) * post.Blog = blog; * } * } * }; */ var fromEntity = infoProvider.FindEntityInfo(memberExpr.Expression.Type); var relation = fromEntity.GetRelation(memberExpr.Member.Name); var toEntity = relation.ToEntity; var fromKey = relation.FromKeys.Single(); var toKey = relation.ToKeys.Single(); var fromProp = relation.FromProperty; var toProp = relation.ToProperty; var fromEnumType = typeof(IEnumerable <>).MakeGenericType(fromEntity.Type); var toEnumType = typeof(IEnumerable <>).MakeGenericType(toEntity.Type); // we need to invert the from and to for parent relation as the expression // was designed for child relation return(toEnumType.IsAssignableFrom(memberExpr.Type) ? MakeFillerFunc(memberExpr, fromEnumType, toEnumType, fromEntity, toEntity, fromKey, toKey, fromProp, toProp) : MakeFillerFunc(memberExpr, toEnumType, fromEnumType, toEntity, fromEntity, toKey, fromKey, toProp, fromProp)); }