public EFCodeFirstTableProvider(EFCodeFirstDataModelProvider dataModel, EntitySet entitySet, EntityType entityType,
            Type entityClrType, Type parentEntityClrType, Type rootEntityClrType, string name)
            : base(dataModel) {

            EntityType = entityClrType;
            Name = name;
            DataContextPropertyName = entitySet.Name;
            ParentEntityType = parentEntityClrType;
            RootEntityType = rootEntityClrType;

            var genericMethod = typeof(ObjectContext).GetMethod("CreateQuery");
            CreateQueryMethod = genericMethod.MakeGenericMethod(EntityType);
            CreateQueryString = CreateEntitySqlQueryString(entitySet);

            var keyMembers = entityType.KeyMembers;

            // columns (entity properties)
            // note 1: keys are also available through es.ElementType.KeyMembers
            // note 2: this includes "nav properties", kind of fancy, two-way relationship objects
            var columns = new List<ColumnProvider>();
            foreach (EdmMember m in entityType.Members) {
                if (EFCodeFirstColumnProvider.IsSupportedEdmMemberType(m) && IsPublicProperty(entityClrType, m.Name)) {
                    EFCodeFirstColumnProvider entityMember = new EFCodeFirstColumnProvider(entityType, this, m, keyMembers.Contains(m));
                    columns.Add(entityMember);
                }
            }

            _roColumns = new ReadOnlyCollection<ColumnProvider>(columns);
        }
        public EFCodeFirstAssociationProvider(EFCodeFirstColumnProvider column, NavigationProperty navigationProperty) {
            FromColumn = column;

            var entityMemberParentEntity = (EFCodeFirstTableProvider)column.Table;
            var parentEntityModel = (EFCodeFirstDataModelProvider)entityMemberParentEntity.DataModel;

            EFCodeFirstColumnProvider columnProvider;
            EntityType otherEntityType = navigationProperty.ToEndMember.GetEntityType();

            // If we can get to the entityType of the ToMember side of the relaionship then build a relationship key and try to lookup the column provider.
            if (otherEntityType != null) {
                long key = BuildRelationshipKey(otherEntityType, navigationProperty.ToEndMember);
                if (parentEntityModel.RelationshipEndLookup.TryGetValue(key, out columnProvider)) {
                    ToColumn = columnProvider;
                }
                else {
                    // Otherwise just lookup the entityType in the table lookup
                    ToTable = parentEntityModel.TableEndLookup[otherEntityType];
                }
            }
            else {
                EntityType value = (EntityType)navigationProperty.ToEndMember.TypeUsage.EdmType.MetadataProperties.Single(prop => prop.Name == "ElementType").Value;
                ToTable = parentEntityModel.TableEndLookup[value];
            }

            if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many) {
                if (navigationProperty.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many) {
                    Direction = AssociationDirection.ManyToMany;
                }
                else {
                    Direction = AssociationDirection.OneToMany;
                }
            }
            else {
                if (navigationProperty.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many) {
                    Direction = AssociationDirection.ManyToOne;
                }
                else {
                    Direction = AssociationDirection.OneToOne;
                }
            }

            // If it's a foreign key reference (as opposed to a entity set), figure out the foreign keys
            if (IsForeignKeyReference) {
                var foreignKeyNames = new List<string>();
                var primaryKeyNames = FromColumn.Table.Columns.Where(c => c.IsPrimaryKey).Select(c => c.Name);

                // Add the foreign keys for this association.
                foreignKeyNames.AddRange(GetDependentPropertyNames(navigationProperty));

                if (IsZeroOrOne(navigationProperty)) {
                    // Assume this is true for 1 to 0..1 relationships on both sides
                    IsPrimaryKeyInThisTable = true;
                }
                else {
                    // If any of the foreign keys are also PKs, set the flag                    
                    IsPrimaryKeyInThisTable = foreignKeyNames.Any(fkName => primaryKeyNames.Contains(fkName, StringComparer.OrdinalIgnoreCase));
                }

                if (!foreignKeyNames.Any()) {
                    // If we couldn't find any dependent properties, we're dealing with a model that doesn't
                    // have FKs, and requires the use of flattened FK names (e.g. Category.CategoryId)
                    foreach (ColumnProvider toEntityColumn in ToTable.Columns.Where(c => c.IsPrimaryKey)) {
                        foreignKeyNames.Add(FromColumn.Name + "." + toEntityColumn.Name);
                    }
                }

                ForeignKeyNames = foreignKeyNames.AsReadOnly();
            }
        }