//todo: temporary public
        public FillingDelegate GetFiller(TypeMappingInfo mapping, Table table)
        {
            var ct = typeof(object);
            // Fill(reader, obj, offset)
            Type[] methodArgs2 = { typeof(IDataRecord), ct, typeof(int) };
            var method = new DynamicMethod(
                "ct",
                null,
                methodArgs2, typeof(SqlValueMapper));

            var generator = method.GetILGenerator();

            Type type = mapping.Type;

            var i = 0;
            foreach(var prop in table.Columns)
            {
                var navigation = prop as NavigationPropertyMapping;
                if (navigation != null)
                {
                    GenerateForNavigationProperty(navigation, type, generator, i);
                }
                else
                {
                    GenerateForPrimitive(type, prop, generator, i);
                }
                i++;
            }
            // return
            generator.Emit(OpCodes.Ret);
            return (FillingDelegate)method.CreateDelegate(typeof(FillingDelegate));
        }
        //todo: temporary public
        public CreatingDelegate GetTypeInstanceCreateDelegate(TypeMappingInfo mapping)
        {
            var ct = typeof(object);
            Type[] methodArgs2 = { typeof(IDataRecord), typeof(int) };

            var method = new DynamicMethod(
                "ct",
                ct,
                methodArgs2, typeof(SqlValueMapper));
            var generator = method.GetILGenerator();
            var localV = generator.DeclareLocal(ct);
            var hierarchy = mapping.Hierarchy;
            var type = mapping.Type;
            if (hierarchy == null || hierarchy.TypeMappings.Count == 1)
            {
                generator.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
            }
            else
            {
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldarg_1);
                generator.Emit(OpCodes.Ldc_I4, 1);
                generator.Emit(OpCodes.Add);
                generator.Emit(OpCodes.Call, GetInt);

                var endOfMethod = generator.DefineLabel();
                var defaultLabel = generator.DefineLabel();
                var jumpTable = hierarchy.TypeMappings.Select(z => generator.DefineLabel()).ToArray();

                generator.Emit(OpCodes.Switch, jumpTable);

                for (var i = 0; i < jumpTable.Length; i++)
                {
                    generator.MarkLabel(jumpTable[i]);
                    generator.Emit(OpCodes.Newobj, hierarchy.TypeMappings[i].Type.GetConstructor(Type.EmptyTypes));
                    generator.Emit(OpCodes.Br, endOfMethod);
                }

                generator.MarkLabel(defaultLabel);
                //todo: make detailed
                generator.ThrowException(typeof(InvalidOperationException));
                generator.MarkLabel(endOfMethod);
            }
            generator.Emit(OpCodes.Stloc, localV);
            generator.Emit(OpCodes.Ldloc, localV);
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldarg_1);
            generator.Emit(OpCodes.Ldc_I4, 0);
            generator.Emit(OpCodes.Add);
            var idProperty = type.GetProperty(mapping.IdentityField);
            generator.Emit(OpCodes.Call, GetGetterMethod(idProperty.PropertyType, false));
            generator.Emit(OpCodes.Call, idProperty.GetSetMethod());
            generator.Emit(OpCodes.Ldloc, localV);
            generator.Emit(OpCodes.Ret);
            return (CreatingDelegate)method.CreateDelegate(typeof(CreatingDelegate));
        }
 public TypeMappingConfig(FluentConfiguration fluentConfiguration, Type type)
 {
     if (fluentConfiguration == null)
         throw new ArgumentNullException("fluentConfiguration");
     if (type == null)
         throw new ArgumentNullException("type");
     _configuration = fluentConfiguration;
     _type = type;
     _mapping = new TypeMappingInfo { Type = type, IdentityField = fluentConfiguration.IdPropertyName };
 }
 //public IEnumerable<PropertyMapping> PropertyMappings { get { return _propertyMappings; } }
 //public IEnumerable<NavigationPropertyMapping> NavigationPropertyMappings { get { return _navigationPropertyMappings.OfType<NavigationPropertyMapping>(); } }
 public void RefillFromParent(TypeMappingInfo parentMapping)
 {
     _tables.InsertRange(0, parentMapping.Tables.OfType<EntityTable>());
     for (var i = 0; i < parentMapping._propertyMappings.Count; i++)
         _propertyMappings.Insert(i, parentMapping._propertyMappings[i]);
 }
        private IEnumerable<SelectPart> Include(SelectSqlBuilder bulder, TableContext mainTableContext, TypeMappingInfo typeMapping, string include)
        {
            var fields = include.Split('.');
            var currentType = typeMapping;
            var context = mainTableContext;
            foreach (var navigationField in fields)
            {
                var navProperty = (NavigationPropertyMapping) currentType.GetProperty(navigationField);
                if (navProperty.Table is PrimitiveListTable)
                {
                    var listContext = GetTableContext(navProperty.Table, "S");
                    bulder.SelectAll(listContext);
                    bulder.LeftOuterJoin(context, listContext, ((EntityTable)context.Table).IdentityColumn.ColumnName, navProperty.Table.Columns.First().ColumnName);
                    yield return new ExpansionPart
                    {
                        Table = navProperty.Table,
                        CollectingType = currentType,
                        CollectingProperty = navProperty
                    };
                    break;
                }

                //todo: no primitive collections totally and no inheritance lookup
                var targetType = navProperty.TargetType;
                var tableInfo = targetType.Tables.OfType<EntityTable>().First();
                var nextcontext = GetTableContext(tableInfo, "S");
                bulder.SelectAll(nextcontext);

                if (navProperty.Host == ReferenceHost.Parent)
                {
                    bulder.LeftOuterJoin(context, nextcontext, navProperty.ColumnName, tableInfo.IdentityColumn.ColumnName);
                }
                else if (navProperty.Host == ReferenceHost.Child)
                {
                    bulder.LeftOuterJoin(context, nextcontext, ((EntityTable)context.Table).IdentityColumn.ColumnName, navProperty.ColumnName);
                }
                else
                    throw new NotImplementedException();
                yield return new SubTypePart
                {
                    Type = targetType,
                    Tables = new[] {tableInfo},
                    CollectingType = currentType,
                    CollectingProperty = navProperty
                };
                currentType = targetType;
                context = nextcontext;
            }
        }
        private void BuildSelectPredicate(SelectSqlBuilder builder, TableContext initialContext, TypeMappingInfo type, string s)
        {
            var fields = s.Split('.');
            var currentType = type;
            var context = initialContext;
            string predicate;
            foreach (var navigationField in fields.Take(fields.Length - 1))
            {
                var navProperty = (NavigationPropertyMapping) type.GetProperty(navigationField);
                var table = navProperty.Table;
                if (table is PrimitiveListTable)
                {
                    builder.Where(PredicateForPrimitiveList(builder, table, context));
                    return;
                }
                currentType = navProperty.TargetType;
                //todo: no primitive collections totally and no inheritance lookup
                var tableInfo = currentType.Tables.OfType<EntityTable>().First();
                var nextcontext = GetTableContext(tableInfo, "T");
                if (navProperty.Host == ReferenceHost.Parent)
                {
                    builder.InnerJoin(context, nextcontext, navProperty.ColumnName, tableInfo.IdentityColumn.ColumnName);
                }
                else if (navProperty.Host == ReferenceHost.Child)
                {
                    builder.InnerJoin(context, nextcontext, ((EntityTable)context.Table).IdentityColumn.ColumnName, navProperty.ColumnName);
                }
                else
                    throw new NotImplementedException();

                context = nextcontext;
            }
            var property = currentType.GetProperty(fields.Last());
            var tbl = property.Table;
            if (tbl is PrimitiveListTable)
            {
                predicate = PredicateForPrimitiveList(builder, tbl, context);
            }
            else
            {
                predicate = builder.GetEquality(GetTableContext(tbl, tbl == initialContext.Table ? "M" : "T"), property.ColumnName, builder.GetNextParameter());
            }
            //todo: think of context and inheritance
            builder.Where(predicate);
        }
 public CreateTableBuilder(TypeMappingInfo mappingInfo)
 {
     if (mappingInfo == null)
         throw new ArgumentNullException("mappingInfo");
     _mappingInfo = mappingInfo;
 }
 public void AddMapping(TypeMappingInfo childType)
 {
     childType.Discriminator = _typeMappings.Count + 1;
     _typeMappings.Add(childType);
 }