Beispiel #1
0
        public static IAssociationLoader <TAssociation> Single <TAssociation>(MetaAssociation association, IValueSet source)
        {
            // Gonna move to DbQueryGenerator
            MetaType otherType = Configuration.Instance.Factory.CreateMapping(typeof(TAssociation));

            StringBuilder builder = new StringBuilder();

            builder.Append("SELECT ");

            foreach (MetaMember member in otherType.Members)
            {
                builder.Append('[').Append(member.GetMemberKey()).Append("],");
            }

            builder.Length--;
            builder.Append(" FROM ");

            if (!String.IsNullOrEmpty(otherType.Schema))
            {
                builder.Append('[').Append(otherType.Schema).Append("].");
            }

            builder.Append('[').Append(otherType.Table).Append("] WHERE [")
            .Append(association.OtherKey).Append("]=@").Append(association.OtherKey);

            ValueDictionary arguments = new ValueDictionary();

            arguments.Add(association.OtherKey, source.GetValue <object>(association.ThisKey));

            return(new SingleMappedAssociationLoader <TAssociation>(new DbCommandDescriptor(builder.ToString(), arguments)));
        }
Beispiel #2
0
        public static IDbSerializer Build(MetaType type)
        {
            Type entityType = type.Type;

            // first build the deserializer method
            DynamicMethod method = new DynamicMethod("Deserialize", entityType,
                                                     new Type[] { typeof(MetaType), entityType, typeof(IDbValueSet) }, entityType, true);

            ILGenerator generator           = method.GetILGenerator();
            short       memberVariableIndex = (short)generator.DeclareLocal(typeof(MetaMember)).LocalIndex;

            foreach (MetaMember member in type.Members)
            {
                if (member.IsAssociation)
                {
                    MetaAssociation association = (MetaAssociation)member;
                    if (association.Accessor.IsDeferred)
                    {
                        EmitDeferredAssociationAssignment(generator, memberVariableIndex, association);
                    }
                }
                else
                {
                    MetaColumn column = (MetaColumn)member;
                    if (column.Accessor.IsDeferred)
                    {
                        EmitDeferredColumnAssignment(generator, memberVariableIndex, column);
                    }
                    else
                    {
                        EmitColumnAssignment(generator, memberVariableIndex, column);
                    }
                }
            }

            generator.Emit(OpCodes.Ldarg_1);
            generator.Emit(OpCodes.Ret);

            Type   serializerType = typeof(DelegatedDbSerializer <>).MakeGenericType(entityType);
            object deserializer   = method.CreateDelegate(typeof(Func <, , ,>).MakeGenericType(
                                                              typeof(MetaType), entityType, typeof(IDbValueSet), entityType));

            return((IDbSerializer)Activator.CreateInstance(serializerType, new object[] { type, null, deserializer }));
        }
Beispiel #3
0
        private static void EmitDeferredAssociationAssignment(ILGenerator generator, short memberVariableIndex, MetaAssociation member)
        {
            string memberName = member.GetMemberKey();

            Type linkedMemberType     = member.Accessor.Type;
            Type linkedElementType    = linkedMemberType.GetSequenceElementType();
            Type linkType             = typeof(ILink <>).MakeGenericType(linkedMemberType);
            Type linkSourceType       = typeof(Func <>).MakeGenericType(linkedMemberType);
            Type associatorLoaderType = typeof(IAssociationLoader <>).MakeGenericType(linkedMemberType);

            MethodInfo associatorFactoryMethod = (member.IsMany)
                                ?  _associationLoaderMultipleMethod.MakeGenericMethod(linkedElementType)
                                :  _associationLoaderSingleMethod.MakeGenericMethod(linkedElementType);
            MethodInfo associationLoadMethod  = associatorLoaderType.GetMethod("Load");
            MethodInfo linkSourceSetterMethod = linkType.GetProperty("Source").GetSetMethod();
            MethodInfo linkValueSetterMethod  = linkType.GetProperty("Value").GetSetMethod();

            ConstructorInfo typeConstructor       = member.Type.GetConstructor(Type.EmptyTypes);
            ConstructorInfo linkSourceConstructor = linkSourceType.GetConstructor(new Type[] { typeof(object), typeof(IntPtr) });

            short variableIndex = (short)generator.DeclareLocal(linkType).LocalIndex;

            Label linkIsNullLabel = generator.DefineLabel();
            Label skipLabel       = generator.DefineLabel();

            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Callvirt, _metaTypeGetMembersMethod);
            generator.Emit(OpCodes.Ldstr, memberName);
            generator.Emit(OpCodes.Callvirt, _metaTypeGetMemberMethod);
            generator.Emit(OpCodes.Stloc, memberVariableIndex);
            generator.Emit(OpCodes.Ldloc, memberVariableIndex);
            generator.Emit(OpCodes.Callvirt, _metaMemberGetAccessorMethod);
            generator.Emit(OpCodes.Ldarg_1);
            generator.Emit(OpCodes.Callvirt, _metaAccessorGetValueMethod);
            generator.Emit(OpCodes.Castclass, linkType);

            generator.Emit(OpCodes.Stloc, variableIndex);
            generator.Emit(OpCodes.Ldloc, variableIndex);

            if (typeConstructor == null)
            {
                generator.Emit(OpCodes.Brtrue, skipLabel);
            }
            else
            {
                generator.Emit(OpCodes.Brtrue, linkIsNullLabel);
            }

            generator.Emit(OpCodes.Newobj, typeConstructor);
            generator.Emit(OpCodes.Stloc, variableIndex);

            generator.MarkLabel(linkIsNullLabel);

            generator.Emit(OpCodes.Ldloc, variableIndex);
            generator.Emit(OpCodes.Ldloc, memberVariableIndex);
            generator.Emit(OpCodes.Castclass, typeof(MetaAssociation));
            generator.Emit(OpCodes.Ldarg_2);
            generator.Emit(OpCodes.Call, associatorFactoryMethod);
            generator.Emit(OpCodes.Dup);
            generator.Emit(OpCodes.Ldvirtftn, associationLoadMethod);
            generator.Emit(OpCodes.Newobj, linkSourceConstructor);
            generator.Emit(OpCodes.Callvirt, linkSourceSetterMethod);

            // here we attempt to decode and write a value.
            //generator.MarkLabel(containsKeyLabel);

            generator.Emit(OpCodes.Ldloc, memberVariableIndex);
            generator.Emit(OpCodes.Callvirt, _metaMemberGetAccessorMethod);
            generator.Emit(OpCodes.Ldarg_1);
            generator.Emit(OpCodes.Ldloc, variableIndex);
            generator.Emit(OpCodes.Callvirt, _metaAccessorSetValueMethod);

            generator.MarkLabel(skipLabel);
        }