/// <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; }