/// <summary>
        /// Given a MetaType and a set of key fields, return the set of MetaDataMembers
        /// corresponding to the key.
        /// </summary>

        protected static ReadOnlyCollection <MetaDataMember> MakeKeys(MetaType mtype, string keyFields)
        {
            string[] names = keyFields.Split(keySeparators);

            var members = new MetaDataMember[names.Length];

            for (int i = 0; i < names.Length; i++)
            {
                names[i] = names[i].Trim();

                MemberInfo[] rmis = mtype.Type.GetMember(names[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

                if (rmis == null || rmis.Length != 1)
                {
                    throw Error.BadKeyMember(names[i], keyFields, mtype.Name);
                }

                members[i] = mtype.GetDataMember(rmis[0]);

                if (members[i] == null)
                {
                    throw Error.BadKeyMember(names[i], keyFields, mtype.Name);
                }
            }

            return(new List <MetaDataMember>(members).AsReadOnly());
        }
        public override MetaDataMember GetDataMember(MemberInfo mi)
        {
            if (mi == null)
            {
                throw Error.ArgumentNull(nameof(mi));
            }

            MetaDataMember mm = null;

            if (this.dataMemberMap.TryGetValue(new MetaPosition(mi), out mm))
            {
                return(mm);
            }

            // DON'T look to see if we are trying to get a member from an inherited type.
            // The calling code should know to look in the inherited type.

            if (mi.DeclaringType.IsInterface)
            {
                throw Error.MappingOfInterfacesMemberIsNotSupported(mi.DeclaringType.Name, mi.Name);
            }

            // the member is not mapped in the base class

            throw Error.UnmappedClassMember(mi.DeclaringType.Name, mi.Name);
        }
        void ValidatePrimaryKeyMember(MetaDataMember mm)
        {
            //if the type is a sub-type, no member declared in the type can be primary key

            if (mm.IsPrimaryKey &&
                this.InheritanceRoot != this &&
                mm.Member.DeclaringType == this.Type)
            {
                throw (Error.PrimaryKeyInSubTypeNotSupported(this.Type.Name, mm.Name));
            }
        }
        void InitSpecialMember(MetaDataMember mm)
        {
            // Can only have one auto gen member that is also an identity member,
            // except if that member is a computed column (since they are implicitly auto gen)

            if (mm.IsDbGenerated &&
                mm.IsPrimaryKey &&
                String.IsNullOrEmpty(mm.Expression))
            {
                if (this.dbGeneratedIdentity != null)
                {
                    throw Error.TwoMembersMarkedAsPrimaryKeyAndDBGenerated(mm.Member, this.dbGeneratedIdentity.Member);
                }

                this.dbGeneratedIdentity = mm;
            }

            if (mm.IsPrimaryKey &&
                !MappingSystem.IsSupportedIdentityType(mm.Type))
            {
                throw Error.IdentityClrTypeNotSupported(mm.DeclaringType, mm.Name, mm.Type);
            }

            if (mm.IsVersion)
            {
                if (this.version != null)
                {
                    throw Error.TwoMembersMarkedAsRowVersion(mm.Member, this.version.Member);
                }

                this.version = mm;
            }

            if (mm.IsDiscriminator)
            {
                if (this.discriminator != null)
                {
                    throw Error.TwoMembersMarkedAsInheritanceDiscriminator(mm.Member, this.discriminator.Member);
                }

                this.discriminator = mm;
            }
        }