/// <summary>
        /// Creates the MetadataWorkspace for the given context type and base context type.
        /// </summary>
        /// <param name="contextType">The type of the context.</param>
        /// <param name="baseContextType">The base context type (DbContext or ObjectContext).</param>
        /// <returns>The generated <see cref="System.Data.Entity.Core.Metadata.Edm.MetadataWorkspace"/></returns>
        public static MetadataWorkspace CreateMetadataWorkspaceFromResources(Type contextType, Type baseContextType)
        {
            // get the set of embedded mapping resources for the target assembly and create
            // a metadata workspace info for each group
            var metadataResourcePaths = FindMetadataResources(contextType.Assembly);
            var workspaceInfos = GetMetadataWorkspaceInfos(metadataResourcePaths);

            // Search for the correct EntityContainer by name and if found, create
            // a comlete MetadataWorkspace and return it
            foreach (var workspaceInfo in workspaceInfos) {
                var edmItemCollection = new EdmItemCollection(workspaceInfo.Csdl);

                var currentType = contextType;
                while (currentType != baseContextType && currentType != typeof (object)) {
                    EntityContainer container;
                    if (edmItemCollection.TryGetEntityContainer(currentType.Name, out container)) {
                        var store = new StoreItemCollection(workspaceInfo.Ssdl);
                        var mapping = new StorageMappingItemCollection(edmItemCollection, store, workspaceInfo.Msl);
                        var workspace = new MetadataWorkspace();
                        workspace.RegisterItemCollection(edmItemCollection);
                        workspace.RegisterItemCollection(store);
                        workspace.RegisterItemCollection(mapping);
                        workspace.RegisterItemCollection(new ObjectItemCollection());
                        return workspace;
                    }

                    currentType = currentType.BaseType;
                }
            }
            return null;
        }
        public void Prepare_returns_a_new_instance()
        {
            var objectQueryExecutionPlanFactory = new ObjectQueryExecutionPlanFactory(
                Common.Internal.Materialization.MockHelper.CreateTranslator<object>());

            var edmItemCollection = new EdmItemCollection();
            var fakeSqlProviderManifest = FakeSqlProviderServices.Instance.GetProviderManifest("2008");
            var storeItemCollection = new StoreItemCollection(FakeSqlProviderFactory.Instance, fakeSqlProviderManifest, "System.Data.SqlClient", "2008");
            var mappingItemCollection = new StorageMappingItemCollection(edmItemCollection, storeItemCollection, Enumerable.Empty<XmlReader>());

            var metadataWorkspace = new MetadataWorkspace(
                () => edmItemCollection,
                () => storeItemCollection,
                () => mappingItemCollection);

            var fakeSqlConnection = new FakeSqlConnection();
            fakeSqlConnection.ConnectionString = "foo";
            var entityConnection = new EntityConnection(metadataWorkspace, fakeSqlConnection, false);

            var objectContext = new ObjectContext(entityConnection);
            var dbExpression = new DbNullExpression(TypeUsage.Create(fakeSqlProviderManifest.GetStoreTypes().First()));
            var dbQueryCommandTree = new DbQueryCommandTree(
                metadataWorkspace, DataSpace.CSpace,
                dbExpression, validate: false);
            var parameters = new List<Tuple<ObjectParameter, QueryParameterExpression>>();

            var objectQueryExecutionPlan = objectQueryExecutionPlanFactory.Prepare(
                objectContext, dbQueryCommandTree, typeof(object),
                MergeOption.NoTracking, false, new Span(), parameters, aliasGenerator: null);

            Assert.NotNull(objectQueryExecutionPlan);
        }
        internal FunctionImportMappingComposable(
            EdmFunction functionImport,
            EdmFunction targetFunction,
            List<Tuple<StructuralType, List<StorageConditionPropertyMapping>, List<StoragePropertyMapping>>> structuralTypeMappings,
            EdmProperty[] targetFunctionKeys,
            StorageMappingItemCollection mappingItemCollection)
            : base(functionImport, targetFunction)
        {
            DebugCheck.NotNull(mappingItemCollection);
            Debug.Assert(functionImport.IsComposableAttribute, "functionImport.IsComposableAttribute");
            Debug.Assert(targetFunction.IsComposableAttribute, "targetFunction.IsComposableAttribute");
            Debug.Assert(
                functionImport.EntitySet == null || structuralTypeMappings != null,
                "Function import returning entities must have structuralTypeMappings.");
            Debug.Assert(
                structuralTypeMappings == null || structuralTypeMappings.Count > 0, "Non-null structuralTypeMappings must not be empty.");
            EdmType resultType;
            Debug.Assert(
                structuralTypeMappings != null ||
                MetadataHelper.TryGetFunctionImportReturnType(functionImport, 0, out resultType) && TypeSemantics.IsScalarType(resultType),
                "Either type mappings should be specified or the function import should be Collection(Scalar).");
            Debug.Assert(
                functionImport.EntitySet == null || targetFunctionKeys != null,
                "Keys must be inferred for a function import returning entities.");
            Debug.Assert(targetFunctionKeys == null || targetFunctionKeys.Length > 0, "Keys must be null or non-empty.");

            m_mappingItemCollection = mappingItemCollection;
            // We will use these parameters to target s-space function calls in the generated command tree. 
            // Since enums don't exist in s-space we need to use the underlying type.
            m_commandParameters =
                functionImport.Parameters.Select(p => TypeHelpers.GetPrimitiveTypeUsageForScalar(p.TypeUsage).Parameter(p.Name)).ToArray();
            m_structuralTypeMappings = structuralTypeMappings;
            m_targetFunctionKeys = targetFunctionKeys;
        }
 /// <summary>
 ///     Returns mappings for the given set/type only if the mapping applies also to childEntittyType either via IsTypeOf or explicitly specifying multiple types in mapping fragments.
 /// </summary>
 private static IEnumerable<StorageTypeMapping> GetIsTypeOfMappingsForEntitySetAndType(
     StorageMappingItemCollection mappingCollection, EntityContainer container, EntitySetBase entitySet, EntityTypeBase entityType,
     EntityTypeBase childEntityType)
 {
     foreach (var mapping in GetMappingsForEntitySetAndType(mappingCollection, container, entitySet, entityType))
     {
         if (mapping.IsOfTypes.Any(parentType => parentType.IsAssignableFrom(childEntityType))
             || mapping.Types.Contains(childEntityType))
         {
             yield return mapping;
         }
     }
 }
 /// <summary>
 ///     Returns all mapping fragments for the given entity set's types and their parent types.
 /// </summary>
 internal static IEnumerable<StorageTypeMapping> GetMappingsForEntitySetAndSuperTypes(
     StorageMappingItemCollection mappingCollection, EntityContainer container, EntitySetBase entitySet,
     EntityTypeBase childEntityType)
 {
     return MetadataHelper.GetTypeAndParentTypesOf(childEntityType, true /*includeAbstractTypes*/).SelectMany(
         edmType =>
             {
                 var entityTypeBase = edmType as EntityTypeBase;
                 return edmType.EdmEquals(childEntityType)
                            ? GetMappingsForEntitySetAndType(mappingCollection, container, entitySet, entityTypeBase)
                            : GetIsTypeOfMappingsForEntitySetAndType(
                                mappingCollection, container, entitySet, entityTypeBase, childEntityType);
             }).ToList();
 }
            internal ViewDictionary(
                StorageMappingItemCollection storageMappingItemCollection,
                out Dictionary<EntitySetBase, GeneratedView> userDefinedQueryViewsDict,
                out Dictionary<OfTypeQVCacheKey, GeneratedView> userDefinedQueryViewsOfTypeDict)
            {
                _storageMappingItemCollection = storageMappingItemCollection;
                _generatedViewsMemoizer =
                    new Memoizer<EntityContainer, Dictionary<EntitySetBase, GeneratedView>>(SerializedGetGeneratedViews, null);
                _generatedViewOfTypeMemoizer = new Memoizer<OfTypeQVCacheKey, GeneratedView>(
                    SerializedGeneratedViewOfType, OfTypeQVCacheKey.PairComparer.Instance);

                userDefinedQueryViewsDict = new Dictionary<EntitySetBase, GeneratedView>(EqualityComparer<EntitySetBase>.Default);
                userDefinedQueryViewsOfTypeDict = new Dictionary<OfTypeQVCacheKey, GeneratedView>(OfTypeQVCacheKey.PairComparer.Instance);

                _tryGetUserDefinedQueryView = userDefinedQueryViewsDict.TryGetValue;
                _tryGetUserDefinedQueryViewOfType = userDefinedQueryViewsOfTypeDict.TryGetValue;
            }
        internal static IEnumerable<StorageTypeMapping> GetMappingsForEntitySetAndType(
            StorageMappingItemCollection mappingCollection, EntityContainer container, EntitySetBase entitySet, EntityTypeBase entityType)
        {
            DebugCheck.NotNull(entityType);
            var containerMapping = GetEntityContainerMap(mappingCollection, container);
            var extentMap = containerMapping.GetSetMapping(entitySet.Name);

            //The Set may have no mapping
            if (extentMap != null)
            {
                //for each mapping fragment of Type we are interested in within the given set
                //Check use of IsOfTypes in Code review
                foreach (var typeMap in extentMap.TypeMappings.Where(map => map.Types.Union(map.IsOfTypes).Contains(entityType)))
                {
                    yield return typeMap;
                }
            }
        }
        internal static IEnumerable<StorageEntityTypeModificationFunctionMapping> GetModificationFunctionMappingsForEntitySetAndType(
            StorageMappingItemCollection mappingCollection, EntityContainer container, EntitySetBase entitySet, EntityTypeBase entityType)
        {
            var containerMapping = GetEntityContainerMap(mappingCollection, container);

            var extentMap = containerMapping.GetSetMapping(entitySet.Name);
            var entitySetMapping = extentMap as StorageEntitySetMapping;

            //The Set may have no mapping
            if (entitySetMapping != null)
            {
                if (entitySetMapping != null) //could be association set mapping
                {
                    foreach (
                        var v in
                            entitySetMapping.ModificationFunctionMappings.Where(functionMap => functionMap.EntityType.Equals(entityType)))
                    {
                        yield return v;
                    }
                }
            }
        }
        private void ValidateWithViewGen(StorageMappingItemCollection mappingItemCollection, EntityDesignArtifact designArtifact)
        {
            Debug.Assert(mappingItemCollection != null, "mappingItemCollection != null");
            Debug.Assert(designArtifact != null, "designArtifact != null");

            var errors = new List<EdmSchemaError>();
            mappingItemCollection.GenerateViews(errors);

            ProcessErrors(errors, designArtifact, ErrorClass.Runtime_ViewGen);
        }
        public static CodeFirstCachedMetadataWorkspace Create(
            StorageMappingItemCollection mappingItemCollection, DbProviderInfo providerInfo)
        {
            var conceptualModel = mappingItemCollection.EdmItemCollection;
            var entityClrTypes = conceptualModel.GetItems<EntityType>().Select(et => et.GetClrType());
            var complexClrTypes = conceptualModel.GetItems<ComplexType>().Select(ct => ct.GetClrType());

            return new CodeFirstCachedMetadataWorkspace(
                mappingItemCollection.Workspace,
                entityClrTypes.Union(complexClrTypes).Select(t => t.Assembly()).Distinct().ToArray(),
                providerInfo,
                conceptualModel.GetItems<EntityContainer>().Single().Name);
        }
        internal static MetadataWorkspace CreateTransientMetadataWorkspace(
            IList<EntitySet> sourceEntitySets,
            Version targetEntityFrameworkVersion,
            string providerInvariantName,
            string providerManifestToken,
            DbProviderManifest providerManifest)
        {
            Debug.Assert(sourceEntitySets != null, "sourceEntitySets != null");
            Debug.Assert(targetEntityFrameworkVersion != null, "targetEntityFrameworkVersion != null");
            Debug.Assert(!string.IsNullOrWhiteSpace(providerInvariantName), "invalid providerInvariantName");
            Debug.Assert(!string.IsNullOrWhiteSpace(providerManifestToken), "invalid providerManifestToken");
            Debug.Assert(providerManifest != null, "providerManifest != null");

            var targetDoubleEntityFrameworkVersion = EntityFrameworkVersion.VersionToDouble(targetEntityFrameworkVersion);

            var storeModel =
                EdmModel.CreateStoreModel(
                    EntityContainer.Create(
                        StoreContainerName,
                        DataSpace.SSpace,
                        sourceEntitySets,
                        Enumerable.Empty<EdmFunction>(),
                        null),
                    new DbProviderInfo(providerInvariantName, providerManifestToken),
                    providerManifest,
                    targetDoubleEntityFrameworkVersion);

            foreach (var entityType in sourceEntitySets.Select(e => e.ElementType))
            {
                storeModel.AddItem(entityType);
            }

            var storeItemCollection = new StoreItemCollection(storeModel);

            var edmItemCollection =
                new EdmItemCollection(
                    EdmModel.CreateConceptualModel(
                        EntityContainer.Create(
                            ModelContainerName,
                            DataSpace.CSpace,
                            Enumerable.Empty<EntitySet>(),
                            Enumerable.Empty<EdmFunction>(),
                            null),
                        targetDoubleEntityFrameworkVersion));

            var msl =
                string.Format(
                    CultureInfo.InvariantCulture,
                    MslTemplate,
                    SchemaManager.GetMSLNamespaceName(targetEntityFrameworkVersion));

            StorageMappingItemCollection mappingItemCollection;

            using (var stringReader = new StringReader(msl))
            {
                using (var reader = XmlReader.Create(stringReader))
                {
                    mappingItemCollection = new StorageMappingItemCollection(edmItemCollection, storeItemCollection, new[] { reader });
                }
            }

            return new MetadataWorkspace(
                () => edmItemCollection,
                () => storeItemCollection,
                () => mappingItemCollection);
        }
        /// <summary>
        /// Factory method that creates a <see cref="StorageMappingItemCollection" />.
        /// </summary>
        /// <param name="edmItemCollection">
        /// The edm metadata collection to map. Must not be <c>null</c>.
        /// </param>
        /// <param name="storeItemCollection">
        /// The store metadata collection to map. Must not be <c>null</c>.
        /// </param>
        /// <param name="xmlReaders">
        /// MSL artifacts to load. Must not be <c>null</c>.
        /// </param>
        /// <param name="filePaths">
        /// Paths to MSL artifacts. Used in error messages. Can be <c>null</c> in which case
        /// the base Uri of the XmlReader will be used as a path.
        /// </param>
        /// <param name="errors">
        /// The collection of errors encountered while loading.
        /// </param>
        /// <returns>
        /// <see cref="EdmItemCollection" /> instance if no errors encountered. Otherwise <c>null</c>.
        /// </returns>
        public static StorageMappingItemCollection Create(
            EdmItemCollection edmItemCollection,
            StoreItemCollection storeItemCollection,
            IEnumerable<XmlReader> xmlReaders,
            IList<string> filePaths,
            out IList<EdmSchemaError> errors)
        {
            Check.NotNull(edmItemCollection, "edmItemCollection");
            Check.NotNull(storeItemCollection, "storeItemCollection");
            Check.NotNull(xmlReaders, "xmlReaders");
            EntityUtil.CheckArgumentContainsNull(ref xmlReaders, "xmlReaders");
            // filePaths is allowed to be null

            var storageMappingItemCollection
                = new StorageMappingItemCollection(edmItemCollection, storeItemCollection, xmlReaders, filePaths, out errors);

            return errors != null && errors.Count > 0 ? null : storageMappingItemCollection;
        }
 internal static StorageEntityContainerMapping GetEntityContainerMap(
     StorageMappingItemCollection mappingCollection, EntityContainer entityContainer)
 {
     var entityContainerMaps = mappingCollection.GetItems<StorageEntityContainerMapping>();
     StorageEntityContainerMapping entityContainerMap = null;
     foreach (var map in entityContainerMaps)
     {
         if ((entityContainer.Equals(map.EdmEntityContainer))
             || (entityContainer.Equals(map.StorageEntityContainer)))
         {
             entityContainerMap = map;
             break;
         }
     }
     if (entityContainerMap == null)
     {
         throw new MappingException(Strings.Mapping_NotFound_EntityContainer(entityContainer.Name));
     }
     return entityContainerMap;
 }
        public void ToLegacyMetadataWorkspace_creates_equivalent_legacy_MetadataWorkspace_for_all_versions()
        {
            const string ssdlTemplate =
                @"<Schema Namespace=""NorthwindEF5Model.Store"" Provider=""System.Data.SqlClient"" ProviderManifestToken=""2008"" Alias=""Self"" xmlns=""{0}"" xmlns:store=""http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"">"
                +
                @"  <EntityType Name=""Customers"">" +
                @"    <Key>" +
                @"      <PropertyRef Name=""CustomerID"" />" +
                @"    </Key>" +
                @"    <Property Name=""CustomerID"" Type=""nchar"" MaxLength=""5"" Nullable=""false"" />" +
                @"    <Property Name=""CompanyName"" Type=""nvarchar"" MaxLength=""40"" Nullable=""false"" />" +
                @"  </EntityType>" +
                @"  <EntityContainer Name=""Container"" />" +
                @"</Schema>";

            const string csdlTemplate =
                @"<Schema xmlns=""{0}"" Namespace=""dummy"">" +
                @"    <EntityContainer Name=""DummyContainer""/>" +
                @"</Schema>";

            const string mslTemplate =
                @"<Mapping Space=""C-S"" xmlns=""{0}"">" +
                @"  <EntityContainerMapping StorageEntityContainer=""Container"" CdmEntityContainer=""DummyContainer"" />" +
                @"</Mapping>";

            foreach (var version in EntityFrameworkVersion.GetAllVersions())
            {
                var storeItemCollection =
                    Utils.CreateStoreItemCollection(
                        string.Format(
                            ssdlTemplate,
                            SchemaManager.GetSSDLNamespaceName(version)));
                var edmItemCollection =
                    new EdmItemCollection(
                        new[]
                            {
                                XmlReader.Create(
                                    new StringReader(
                                        string.Format(
                                            csdlTemplate,
                                            SchemaManager.GetCSDLNamespaceName(version))))
                            });
                var mappingItemCollection =
                    new StorageMappingItemCollection(
                        edmItemCollection,
                        storeItemCollection,
                        new[]
                            {
                                XmlReader.Create(
                                    new StringReader(
                                        string.Format(
                                            mslTemplate,
                                            SchemaManager.GetMSLNamespaceName(version))))
                            });
                var workspace = new MetadataWorkspace(
                    () => edmItemCollection,
                    () => storeItemCollection,
                    () => mappingItemCollection);

                var legacyWorkspace = workspace.ToLegacyMetadataWorkspace();

                Assert.NotNull(legacyWorkspace);

                var legacyStoreItemCollection = legacyWorkspace.GetItemCollection(LegacyMetadata.DataSpace.SSpace);

                Assert.Equal(
                    storeItemCollection.GetItems<GlobalItem>().Count,
                    legacyStoreItemCollection.GetItems<LegacyMetadata.GlobalItem>().Count);

                Assert.NotNull(
                    legacyStoreItemCollection.GetItem<LegacyMetadata.EntityType>("NorthwindEF5Model.Store.Customers"));

                var legacyEdmItemCollection =
                    (LegacyMetadata.EdmItemCollection)legacyWorkspace.GetItemCollection(LegacyMetadata.DataSpace.CSpace);
                Assert.NotNull(legacyEdmItemCollection);
                Assert.Equal(version, EntityFrameworkVersion.DoubleToVersion(legacyEdmItemCollection.EdmVersion));

                Assert.NotNull(legacyWorkspace.GetItemCollection(LegacyMetadata.DataSpace.CSSpace));
            }
        }
        private static MetadataWorkspace CreateMetadataWorkspace()
        {
            var sqlCeProviderServices = DbProviderServices.GetProviderServices(new SqlCeConnection());
            var sqlCeProviderManifest = sqlCeProviderServices.GetProviderManifest("4.0");

            var edmItemCollection = new EdmItemCollection(
                new[] { DbProviderServices.GetConceptualSchemaDefinition("ConceptualSchemaDefinition") });
            var storeItemCollection = new StoreItemCollection(
                new[] { sqlCeProviderManifest.GetInformation("StoreSchemaDefinition") });
            var mappingItemCollection = new StorageMappingItemCollection(edmItemCollection, storeItemCollection,
                new[] { sqlCeProviderManifest.GetInformation("StoreSchemaMapping") });

            return new MetadataWorkspace(() => edmItemCollection, () => storeItemCollection, () => mappingItemCollection);
        }
        public void WriteFunctionImportMappingElement_writes_result_mapping_for_non_composable_functions_mapped_explicitly_to_EntityType()
        {
            var typeUsage =
                TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32));

            var entityTypeProperty1 = new EdmProperty("ETProperty1", typeUsage);
            var entityTypeProperty2 = new EdmProperty("ETProperty2", typeUsage);

            var entityType = new EntityType("ET", "Ns", DataSpace.CSpace);
            entityType.AddMember(entityTypeProperty1);
            entityType.AddMember(entityTypeProperty2);

            var functionImport =
                new EdmFunction(
                    "f_c", "Ns", DataSpace.CSpace,
                    new EdmFunctionPayload
                    {
                        IsComposable = false,
                        IsFunctionImport = true,
                        ReturnParameters =
                            new[]
                                    {
                                        new FunctionParameter(
                                            "ReturnValue",
                                            TypeUsage.CreateDefaultTypeUsage(entityType.GetCollectionType()),
                                            ParameterMode.ReturnValue)
                                    },
                    });

            typeUsage = ProviderRegistry.Sql2008_ProviderManifest.GetStoreType(typeUsage);
            var rowTypeProperty1 = new EdmProperty("RTProperty1", typeUsage);
            var rowTypeProperty2 = new EdmProperty("RTProperty2", typeUsage);
            var rowType = new RowType(new[] { rowTypeProperty1, rowTypeProperty2 });

            var storeFunction =
                new EdmFunction(
                    "f_s", "Ns.Store", DataSpace.SSpace,
                    new EdmFunctionPayload
                    {
                        IsComposable = false,
                        ReturnParameters =
                            new[]
                                    {
                                        new FunctionParameter(
                                            "Return",
                                            TypeUsage.CreateDefaultTypeUsage(rowType),
                                            ParameterMode.ReturnValue)
                                    },
                    });

            var functionImportResultMapping = new FunctionImportResultMapping();
            functionImportResultMapping.AddTypeMapping(
                new FunctionImportEntityTypeMapping(
                    new EntityType[0],
                    new [] { entityType },
                    new Collections.ObjectModel.Collection<FunctionImportReturnTypePropertyMapping>()
                    {
                        new FunctionImportReturnTypeScalarPropertyMapping("ETProperty1", "RTProperty1"),
                        new FunctionImportReturnTypeScalarPropertyMapping("ETProperty2", "RTProperty2")
                    },
                    new FunctionImportEntityTypeMappingCondition[]
                    {
                        new FunctionImportEntityTypeMappingConditionIsNull("RTProperty1", false),
                        new FunctionImportEntityTypeMappingConditionValue("RTProperty2", 4),
                        new FunctionImportEntityTypeMappingConditionValue("FakeCondition", true)
                    }
                ));

            var mappingItemCollection = 
                new StorageMappingItemCollection(
                    new EdmItemCollection(EdmModel.CreateConceptualModel()), 
                    new StoreItemCollection(
                        EdmModel.CreateStoreModel(ProviderRegistry.Sql2008_ProviderInfo, ProviderRegistry.Sql2008_ProviderManifest)), 
                        new string[0]);

            var containerMapping = 
                new EntityContainerMapping(
                    new EntityContainer("C", DataSpace.CSpace), new EntityContainer("S", DataSpace.SSpace), mappingItemCollection, false);

            var functionImportMapping =
                new FunctionImportMappingNonComposable(
                   functionImport,
                   storeFunction,
                   new []
                   {
                       functionImportResultMapping
                   },
                   containerMapping);

            containerMapping.AddFunctionImportMapping(functionImportMapping);

            var fixture = new Fixture();
            fixture.Writer.WriteFunctionImportMappingElement(functionImportMapping);
            Assert.Equal(
                @"<FunctionImportMapping FunctionName=""Ns.Store.f_s"" FunctionImportName=""f_c"">
  <ResultMapping>
    <EntityTypeMapping TypeName=""Ns.ET"">
      <ScalarProperty Name=""ETProperty1"" ColumnName=""RTProperty1"" />
      <ScalarProperty Name=""ETProperty2"" ColumnName=""RTProperty2"" />
      <Condition ColumnName=""RTProperty1"" IsNull=""false"" />
      <Condition ColumnName=""RTProperty2"" Value=""4"" />
      <Condition ColumnName=""FakeCondition"" Value=""1"" />
    </EntityTypeMapping>
  </ResultMapping>
</FunctionImportMapping>",
                fixture.ToString());
        }
        public void MappingViewCacheFactory_can_be_set_and_retrieved()
        {
            var itemCollection = new StorageMappingItemCollection();
            var factory = new SampleMappingViewCacheFactory("value");

            itemCollection.MappingViewCacheFactory = factory;

            Assert.Same(factory, itemCollection.MappingViewCacheFactory);
        }
            // <summary>
            // Returns the update or query view for an Extent as a
            // string.
            // There are a series of steps that we go through for discovering a view for an extent.
            // To start with we assume that we are working with Generated Views. To find out the
            // generated view we go to the ObjectItemCollection and see if it is not-null. If the ObjectItemCollection
            // is non-null, we get the view generation assemblies that it might have cached during the
            // Object metadata discovery.If there are no view generation assemblies we switch to the
            // runtime view generation strategy. If there are view generation assemblies, we get the list and
            // go through them and see if there are any assemblies that are there from which we have not already loaded
            // the views. We collect the views from assemblies that we have not already collected from earlier.
            // If the ObjectItemCollection is null and we are in the view generation mode, that means that
            // the query or update is issued from the Value layer and this is the first time view has been asked for.
            // The compile time view gen for value layer queries will work for very simple scenarios.
            // If the users wants to get the performance benefit, they should call MetadataWorkspace.LoadFromAssembly.
            // At this point we go through the referenced assemblies of the entry assembly( this wont work for Asp.net
            // or if the viewgen assembly was not referenced by the executing application).
            // and try to see if there were any view gen assemblies. If there are, we collect the views for all extents.
            // Once we have all the generated views gathered, we try to get the view for the extent passed in.
            // If we find one we will return it. If we can't find one an exception will be thrown.
            // If there were no view gen assemblies either in the ObjectItemCollection or in the list of referenced
            // assemblies of calling assembly, we change the mode to runtime view generation and will continue to
            // be in that mode for the rest of the lifetime of the mapping item collection.
            // </summary>
            internal GeneratedView GetGeneratedView(
                EntitySetBase extent, MetadataWorkspace workspace, StorageMappingItemCollection storageMappingItemCollection)
            {
                //First check if we have collected a view from user-defined query views
                //Dont need to worry whether to generate Query view or update viw, because that is relative to the extent.
                GeneratedView view;

                if (_tryGetUserDefinedQueryView(extent, out view))
                {
                    return view;
                }

                //If this is a foreign key association, manufacture a view on the fly.
                if (extent.BuiltInTypeKind
                    == BuiltInTypeKind.AssociationSet)
                {
                    var aSet = (AssociationSet)extent;
                    if (aSet.ElementType.IsForeignKey)
                    {
                        if (_config.IsViewTracing)
                        {
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.FormatTraceLine("================= Generating FK Query View for: {0} =================", aSet.Name);
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.StringTraceLine(String.Empty);
                        }

                        // Although we expose a collection of constraints in the API, there is only ever one constraint.
                        Debug.Assert(
                            aSet.ElementType.ReferentialConstraints.Count == 1, "aSet.ElementType.ReferentialConstraints.Count == 1");
                        var rc = aSet.ElementType.ReferentialConstraints.Single();

                        var dependentSet = aSet.AssociationSetEnds[rc.ToRole.Name].EntitySet;
                        var principalSet = aSet.AssociationSetEnds[rc.FromRole.Name].EntitySet;

                        DbExpression qView = dependentSet.Scan();

                        // Introduce an OfType view if the dependent end is a subtype of the entity set
                        var dependentType = MetadataHelper.GetEntityTypeForEnd((AssociationEndMember)rc.ToRole);
                        var principalType = MetadataHelper.GetEntityTypeForEnd((AssociationEndMember)rc.FromRole);
                        if (dependentSet.ElementType.IsBaseTypeOf(dependentType))
                        {
                            qView = qView.OfType(TypeUsage.Create(dependentType));
                        }

                        if (rc.FromRole.RelationshipMultiplicity
                            == RelationshipMultiplicity.ZeroOrOne)
                        {
                            // Filter out instances with existing relationships.
                            qView = qView.Where(
                                e =>
                                {
                                    DbExpression filter = null;
                                    foreach (var fkProp in rc.ToProperties)
                                    {
                                        DbExpression notIsNull = e.Property(fkProp).IsNull().Not();
                                        filter = null == filter ? notIsNull : filter.And(notIsNull);
                                    }
                                    return filter;
                                });
                        }
                        qView = qView.Select(
                            e =>
                            {
                                var ends = new List<DbExpression>();
                                foreach (var end in aSet.ElementType.AssociationEndMembers)
                                {
                                    if (end.Name
                                        == rc.ToRole.Name)
                                    {
                                        var keyValues = new List<KeyValuePair<string, DbExpression>>();
                                        foreach (var keyMember in dependentSet.ElementType.KeyMembers)
                                        {
                                            keyValues.Add(e.Property((EdmProperty)keyMember));
                                        }
                                        ends.Add(dependentSet.RefFromKey(DbExpressionBuilder.NewRow(keyValues), dependentType));
                                    }
                                    else
                                    {
                                        // Manufacture a key using key values.
                                        var keyValues = new List<KeyValuePair<string, DbExpression>>();
                                        foreach (var keyMember in principalSet.ElementType.KeyMembers)
                                        {
                                            var offset = rc.FromProperties.IndexOf((EdmProperty)keyMember);
                                            keyValues.Add(e.Property(rc.ToProperties[offset]));
                                        }
                                        ends.Add(principalSet.RefFromKey(DbExpressionBuilder.NewRow(keyValues), principalType));
                                    }
                                }
                                return TypeUsage.Create(aSet.ElementType).New(ends);
                            });
                        return GeneratedView.CreateGeneratedViewForFKAssociationSet(
                            aSet, aSet.ElementType, new DbQueryCommandTree(workspace, DataSpace.SSpace, qView), storageMappingItemCollection,
                            _config);
                    }
                }

                // If no User-defined QV is found, call memoized View Generation procedure.
                var generatedViews = _generatedViewsMemoizer.Evaluate(extent.EntityContainer);

                if (!generatedViews.TryGetValue(extent, out view))
                {
                    throw new InvalidOperationException(
                        Strings.Mapping_Views_For_Extent_Not_Generated(
                            (extent.EntityContainer.DataSpace == DataSpace.SSpace) ? "Table" : "EntitySet", extent.Name));
                }

                return view;
            }
        public void MappingViewCacheFactory_cannot_be_changed()
        {
            var itemCollection = new StorageMappingItemCollection();

            var factory1 = new SampleMappingViewCacheFactory("value1");
            var factory2 = new SampleMappingViewCacheFactory("value1");
            var factory3 = new SampleMappingViewCacheFactory("value2");

            itemCollection.MappingViewCacheFactory = factory1;

            // Set with same instance does not throw.
            itemCollection.MappingViewCacheFactory = factory1;

            // Set with new instance and equal value does not throw.
            itemCollection.MappingViewCacheFactory = factory2;

            // Set with new instance and different value throws.
            var exception = new ArgumentException(Strings.MappingViewCacheFactory_MustNotChange, "value");
            Assert.Equal(exception.Message,
                Assert.Throws<ArgumentException>(
                    () => itemCollection.MappingViewCacheFactory = factory3).Message);
        }
        private static MetadataWorkspace CreateMetadataWorkspace()
        {
            const string ssdl =
                @"<Schema Namespace=""NorthwindEF5Model.Store"" Provider=""System.Data.SqlClient"" ProviderManifestToken=""2008"" Alias=""Self"" xmlns=""http://schemas.microsoft.com/ado/2009/11/edm/ssdl"" xmlns:store=""http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"">"
                +
                @"  <EntityType Name=""Customers"">" +
                @"    <Key>" +
                @"      <PropertyRef Name=""CustomerID"" />" +
                @"    </Key>" +
                @"    <Property Name=""CustomerID"" Type=""nchar"" MaxLength=""5"" Nullable=""false"" />" +
                @"    <Property Name=""CompanyName"" Type=""nvarchar"" MaxLength=""40"" Nullable=""false"" />" +
                @"  </EntityType>" +
                @"  <EntityContainer Name=""Container"" />" +
                @"</Schema>";

            const string csdl =
                @"<Schema xmlns=""http://schemas.microsoft.com/ado/2009/11/edm"" Namespace=""dummy"">" +
                @"    <EntityContainer Name=""DummyContainer""/>" +
                @"</Schema>";

            const string msl =
                @"<Mapping Space=""C-S"" xmlns=""http://schemas.microsoft.com/ado/2009/11/mapping/cs"">" +
                @"  <EntityContainerMapping StorageEntityContainer=""Container"" CdmEntityContainer=""DummyContainer"" />" +
                @"</Mapping>";

            var storeItemCollection = Utils.CreateStoreItemCollection(ssdl);
            var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(csdl)) });
            var mappingItemCollection =
                new StorageMappingItemCollection(
                    edmItemCollection,
                    storeItemCollection,
                    new[] { XmlReader.Create(new StringReader(msl)) });

            return new MetadataWorkspace(() => edmItemCollection, () => storeItemCollection, () => mappingItemCollection);
        }
        internal static StorageMappingItemCollection CreateStorageMappingItemCollection(string ssdl, string csdl, string msl)
        {
            StoreItemCollection storeCollection;
            EdmItemCollection edmCollection;
            StorageMappingItemCollection mappingCollection;

            using (var stringReader = new StringReader(ssdl))
            using (var xmlReader = XmlReader.Create(stringReader))
            {
                storeCollection = new StoreItemCollection(new[] { xmlReader });
            }

            using (var stringReader = new StringReader(csdl))
            using (var xmlReader = XmlReader.Create(stringReader))
            {
                edmCollection = new EdmItemCollection(new[] { xmlReader });
            }

            using (var stringReader = new StringReader(msl))
            using (var xmlReader = XmlReader.Create(stringReader))
            {
                mappingCollection = new StorageMappingItemCollection(edmCollection, storeCollection, new[] { xmlReader });
            }

            return mappingCollection;
        }