private static LegacyMetadata.EdmItemCollection GetLegacyEdmItemCollection(Version version) { const string csdlTemplate = @"<Schema xmlns=""{0}"" Namespace=""dummy"">" + @" <EntityContainer Name=""DummyContainer""/>" + @"</Schema>"; LegacyMetadata.EdmItemCollection itemCollection; if (!LegacyEdmItemCollections.TryGetValue(version, out itemCollection)) { var csdl = string.Format(CultureInfo.InvariantCulture, csdlTemplate, SchemaManager.GetCSDLNamespaceName(version)); using (var stringReader = new StringReader(csdl)) { using (var reader = XmlReader.Create(stringReader)) { itemCollection = new LegacyMetadata.EdmItemCollection(new[] { reader }); LegacyEdmItemCollections[version] = itemCollection; } } } return(itemCollection); }
public StorageMappingItemCollection(EdmItemCollection edmCollection, StoreItemCollection storeCollection, params string[] filePaths) : base(DataSpace.CSSpace) { EntityUtil.CheckArgumentNull(edmCollection, "edmCollection"); EntityUtil.CheckArgumentNull(storeCollection, "storeCollection"); EntityUtil.CheckArgumentNull(filePaths, "filePaths"); this.m_edmCollection = edmCollection; this.m_storeItemCollection = storeCollection; // Wrap the file paths in instances of the MetadataArtifactLoader class, which provides // an abstraction and a uniform interface over a diverse set of metadata artifacts. // MetadataArtifactLoader composite = null; List<XmlReader> readers = null; try { composite = MetadataArtifactLoader.CreateCompositeFromFilePaths(filePaths, XmlConstants.CSSpaceSchemaExtension); readers = composite.CreateReaders(DataSpace.CSSpace); this.Init(edmCollection, storeCollection, readers, composite.GetPaths(DataSpace.CSSpace), true /*throwOnError*/); } finally { if (readers != null) { Helper.DisposeXmlReaders(readers); } } }
private static MetadataWorkspace CreateWrappedMetadataWorkspace(string metadata, IEnumerable<string> wrapperProviderNames) { MetadataWorkspace workspace = new MetadataWorkspace(); // parse Metadata keyword and load CSDL,SSDL,MSL files into XElement structures... var csdl = new List<XElement>(); var ssdl = new List<XElement>(); var msl = new List<XElement>(); ParseMetadata(metadata, csdl, ssdl, msl); // fix all SSDL files by changing 'Provider' to our provider and modifying foreach (var ssdlFile in ssdl) { foreach (string providerName in wrapperProviderNames) { ssdlFile.Attribute("ProviderManifestToken").Value = ssdl[0].Attribute("Provider").Value + ";" + ssdlFile.Attribute("ProviderManifestToken").Value; ssdlFile.Attribute("Provider").Value = providerName; } } // load item collections from XML readers created from XElements... EdmItemCollection eic = new EdmItemCollection(csdl.Select(c => c.CreateReader())); StoreItemCollection sic = new StoreItemCollection(ssdl.Select(c => c.CreateReader())); StorageMappingItemCollection smic = new StorageMappingItemCollection(eic, sic, msl.Select(c => c.CreateReader())); // and create metadata workspace based on them. workspace = new MetadataWorkspace(); workspace.RegisterItemCollection(eic); workspace.RegisterItemCollection(sic); workspace.RegisterItemCollection(smic); return workspace; }
private MemberDomainMap(Dictionary<MemberPath, CellConstantSet> domainMap, Dictionary<MemberPath, CellConstantSet> nonConditionDomainMap, EdmItemCollection edmItemCollection) { m_conditionDomainMap = domainMap; m_nonConditionDomainMap = nonConditionDomainMap; m_edmItemCollection = edmItemCollection; }
internal static void LoadAssembly( Assembly assembly, bool loadReferencedAssemblies, KnownAssembliesSet knownAssemblies, EdmItemCollection edmItemCollection, Action<String> logLoadMessage, ref object loaderCookie, out Dictionary<string, EdmType> typesInLoading, out List<EdmItemError> errors) { Debug.Assert( loaderCookie == null || loaderCookie is Func<Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>, "This is a bad loader cookie"); typesInLoading = null; errors = null; using (var lockedAssemblyCache = AquireLockedAssemblyCache()) { var loadingData = new ObjectItemLoadingSessionData( knownAssemblies, lockedAssemblyCache, edmItemCollection, logLoadMessage, loaderCookie); LoadAssembly(assembly, loadReferencedAssemblies, loadingData); loaderCookie = loadingData.LoaderCookie; // resolve references to top level types (base types, navigation properties returns and associations, and complex type properties) loadingData.CompleteSession(); if (loadingData.EdmItemErrors.Count == 0) { // do the validation for the all the new types // Now, perform validation on all the new types var validator = new EdmValidator(); validator.SkipReadOnlyItems = true; validator.Validate(loadingData.TypesInLoading.Values, loadingData.EdmItemErrors); // Update the global cache if there are no errors if (loadingData.EdmItemErrors.Count == 0) { if (ObjectItemAssemblyLoader.IsAttributeLoader(loadingData.ObjectItemAssemblyLoaderFactory)) { // we only cache items from the attribute loader globally, the // items loaded by convention will change depending on the cspace // provided. cspace will have a cache of it's own for assemblies UpdateCache(lockedAssemblyCache, loadingData.AssembliesLoaded); } else if (loadingData.EdmItemCollection != null && ObjectItemAssemblyLoader.IsConventionLoader(loadingData.ObjectItemAssemblyLoaderFactory)) { UpdateCache(loadingData.EdmItemCollection, loadingData.AssembliesLoaded); } } } if (loadingData.TypesInLoading.Count > 0) { foreach (var edmType in loadingData.TypesInLoading.Values) { edmType.SetReadOnly(); } } // Update the out parameters once you are done with loading typesInLoading = loadingData.TypesInLoading; errors = loadingData.EdmItemErrors; } }
/// <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="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 IEnumerable<string> metadataResourcePaths = FindMetadataResources(contextType.Assembly); IEnumerable<MetadataWorkspaceInfo> 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) { EdmItemCollection edmItemCollection = new EdmItemCollection(workspaceInfo.Csdl); Type currentType = contextType; while (currentType != baseContextType && currentType != typeof(object)) { EntityContainer container; if (edmItemCollection.TryGetEntityContainer(currentType.Name, out container)) { StoreItemCollection store = new StoreItemCollection(workspaceInfo.Ssdl); StorageMappingItemCollection mapping = new StorageMappingItemCollection(edmItemCollection, store, workspaceInfo.Msl); MetadataWorkspace workspace = new MetadataWorkspace(); workspace.RegisterItemCollection(edmItemCollection); workspace.RegisterItemCollection(store); workspace.RegisterItemCollection(mapping); workspace.RegisterItemCollection(new ObjectItemCollection()); return workspace; } currentType = currentType.BaseType; } } return null; }
/// <summary> /// Recursively generates <see cref="MemberPath"/>s for the members of the types stored in the <paramref name="extent"/>. /// </summary> internal static MemberProjectionIndex Create(EntitySetBase extent, EdmItemCollection edmItemCollection) { // We generate the indices for the projected slots as we traverse the metadata. MemberProjectionIndex index = new MemberProjectionIndex(); GatherPartialSignature(index, edmItemCollection, new MemberPath(extent), false); // need not only keys return index; }
public bool HaveSeenInCompatibleContext(object loaderCookie, EdmItemCollection itemCollection) { // a new "context" is only when we have not seen this assembly with an itemCollection that is non-null // and we now have a non-null itemCollection, and we are not already in AttributeLoader mode. return SeenWithEdmItemCollection || itemCollection == null || ObjectItemAssemblyLoader.IsAttributeLoader(loaderCookie); }
/// <summary> /// Constrcutor to create an instance of DefaultObjectMappingItemCollection. /// To start with we will create a Schema under which maps will be created. /// </summary> /// <param name="edmCollection"></param> /// <param name="objectCollection"></param> public DefaultObjectMappingItemCollection(EdmItemCollection edmCollection, ObjectItemCollection objectCollection) : base(DataSpace.OCSpace) { EntityUtil.CheckArgumentNull(edmCollection, "edmCollection"); EntityUtil.CheckArgumentNull(objectCollection, "objectCollection"); this.m_edmCollection = edmCollection; this.m_objectCollection = objectCollection; LoadPrimitiveMaps(); }
public static void InitializeMetadataWorkspace(TestContext testContext) { StringReader sr = new StringReader(testCsdl); XmlReader reader = XmlReader.Create(sr); metadataWorkspace = new MetadataWorkspace(); EdmItemCollection edmItemCollection = new EdmItemCollection(new XmlReader[] { reader }); metadataWorkspace.RegisterItemCollection(edmItemCollection); metadataWorkspace.RegisterItemCollection(new ObjectItemCollection()); metadataWorkspace.LoadFromAssembly(Assembly.GetExecutingAssembly()); }
public EdmDataModelProvider(Uri serviceUri, bool isReadonly, bool supportPagingAndSorting) { var context = new DataServiceContext(serviceUri); Uri metadataUri = context.GetMetadataUri(); var doc = XDocument.Load(metadataUri.AbsoluteUri); var itemCollection = new EdmItemCollection(GetSchemas(doc).Select(s => s.CreateReader())); RelationshipEndLookup = new Dictionary<long, EdmColumnProvider>(); TableEndLookup = new Dictionary<EntityType, EdmTableProvider>(); var tables = new List<TableProvider>(); // Create a dictionary from entity type to entity set. The entity type should be at the root of any inheritance chain. IDictionary<EntityType, EntitySet> entitySetLookup = itemCollection.GetItems<EntityContainer>().SelectMany(c => c.BaseEntitySets.OfType<EntitySet>()).ToDictionary(e => e.ElementType); // Create a lookup from parent entity to entity ILookup<EntityType, EntityType> derivedTypesLookup = itemCollection.GetItems<EntityType>().ToLookup(e => (EntityType)e.BaseType); _complexTypes = itemCollection.GetItems<ComplexType>(); // Keeps track of the current entity set being processed EntitySet currentEntitySet = null; // Do a DFS to get the inheritance hierarchy in order // i.e. Consider the hierarchy // null -> Person // Person -> Employee, Contact // Employee -> SalesPerson, Programmer // We'll walk the children in a depth first order -> Person, Employee, SalesPerson, Programmer, Contact. var objectStack = new Stack<EntityType>(); // Start will null (the root of the hierarchy) objectStack.Push(null); while (objectStack.Any()) { EntityType entityType = objectStack.Pop(); if (entityType != null) { // Update the entity set when we are at another root type (a type without a base type). if (entityType.BaseType == null) { currentEntitySet = entitySetLookup[entityType]; } var table = CreateTableProvider(currentEntitySet, entityType, isReadonly, supportPagingAndSorting); tables.Add(table); } foreach (EntityType derivedEntityType in derivedTypesLookup[entityType]) { // Push the derived entity types on the stack objectStack.Push(derivedEntityType); } } _tables = tables.AsReadOnly(); GenerateClrTypes(serviceUri); }
/// <summary> /// Constrcutor to create an instance of DefaultObjectMappingItemCollection. /// To start with we will create a Schema under which maps will be created. /// </summary> /// <param name="edmCollection"></param> /// <param name="objectCollection"></param> public DefaultObjectMappingItemCollection( EdmItemCollection edmCollection, ObjectItemCollection objectCollection) : base(DataSpace.OCSpace) { //Contract.Requires(edmCollection != null); //Contract.Requires(objectCollection != null); m_edmCollection = edmCollection; m_objectCollection = objectCollection; LoadPrimitiveMaps(); }
public ClientApiGenerator(Schema sourceSchema, EdmItemCollection edmItemCollection, EntityClassGenerator generator, List<EdmSchemaError> errors) { Debug.Assert(sourceSchema != null, "sourceSchema is null"); Debug.Assert(edmItemCollection != null, "edmItemCollection is null"); Debug.Assert(generator != null, "generator is null"); Debug.Assert(errors != null, "errors is null"); _edmItemCollection = edmItemCollection; _sourceSchema = sourceSchema; _generator = generator; _errors = errors; _attributeEmitter = new AttributeEmitter(_typeReference); }
internal bool TryGetKnownAssembly(Assembly assembly, object loaderCookie, EdmItemCollection itemCollection, out KnownAssemblyEntry entry) { if (!_assemblies.TryGetValue(assembly, out entry)) { return false; } if (!entry.HaveSeenInCompatibleContext(loaderCookie, itemCollection)) { return false; } return true; }
/// <summary> /// Attempts to create a EdmItemCollection from the specified metadata file /// </summary> public bool TryCreateEdmItemCollection(string sourcePath, string[] referenceSchemas, out EdmItemCollection edmItemCollection) { edmItemCollection = null; if(String.IsNullOrEmpty(sourcePath)) throw new ArgumentException("sourcePath"); if(referenceSchemas == null) referenceSchemas = new string[0]; ItemCollection itemCollection = null; sourcePath = _textTransformation.Host.ResolvePath(sourcePath); var collectionBuilder = new EdmItemCollectionBuilder(_textTransformation, referenceSchemas.Select(s => _textTransformation.Host.ResolvePath(s)).Where(s => s != sourcePath)); if(collectionBuilder.TryCreateItemCollection(sourcePath, out itemCollection)) edmItemCollection = (EdmItemCollection) itemCollection; return edmItemCollection != null; }
protected override void Visit(StorageEntityContainerMapping storageEntityContainerMapping) { Debug.Assert(storageEntityContainerMapping != null, "storageEntityContainerMapping cannot be null!"); // at the entry point of visitor, we setup the versions Debug.Assert(m_MappingVersion == storageEntityContainerMapping.StorageMappingItemCollection.MappingVersion, "the original version and the mapping collection version are not the same"); this.m_MappingVersion = storageEntityContainerMapping.StorageMappingItemCollection.MappingVersion; this.m_EdmVersion = storageEntityContainerMapping.StorageMappingItemCollection.EdmItemCollection.EdmVersion; this.m_EdmItemCollection = storageEntityContainerMapping.StorageMappingItemCollection.EdmItemCollection; int index; if (!this.AddObjectToSeenListAndHashBuilder(storageEntityContainerMapping, out index)) { // if this has been add to the seen list, then just return; } if (this.m_itemsAlreadySeen.Count > 1) { // this means user try another visit over SECM, this is allowed but all the previous visit all lost due to clean // user can visit different SECM objects by using the same visitor to load the SECM object this.Clean(); Visit(storageEntityContainerMapping); return; } this.AddObjectStartDumpToHashBuilder(storageEntityContainerMapping, index); #region Inner data visit this.AddObjectContentToHashBuilder(storageEntityContainerMapping.Identity); this.AddV2ObjectContentToHashBuilder(storageEntityContainerMapping.GenerateUpdateViews, this.m_MappingVersion); base.Visit(storageEntityContainerMapping); #endregion this.AddObjectEndDumpToHashBuilder(); }
private static StorageMappingItemCollection ToStorageMappingItemCollection( this DbDatabaseMapping databaseMapping, EdmItemCollection itemCollection, StoreItemCollection storeItemCollection) { //Contract.Requires(databaseMapping != null); //Contract.Requires(itemCollection != null); //Contract.Requires(storeItemCollection != null); var stringBuilder = new StringBuilder(); using (var xmlWriter = XmlWriter.Create( stringBuilder, new XmlWriterSettings { Indent = true })) { new MslSerializer().Serialize(databaseMapping, xmlWriter); } using (var xmlReader = XmlReader.Create(new StringReader(stringBuilder.ToString()))) { return new StorageMappingItemCollection(itemCollection, storeItemCollection, new[] { xmlReader }); } }
/// <summary> /// Compiles eSQL <paramref name="functionDefinition"/> and returns <see cref="DbLambda"/>. /// Guarantees type match of lambda variables and <paramref name="functionParameters"/>. /// Passes thru all excepions coming from <see cref="CqlQuery"/>. /// </summary> internal static DbLambda CompileFunctionDefinition( string functionDefinition, IList<FunctionParameter> functionParameters, EdmItemCollection edmItemCollection) { Debug.Assert(functionParameters != null, "functionParameters != null"); Debug.Assert(edmItemCollection != null, "edmItemCollection != null"); var workspace = new MetadataWorkspace(); workspace.RegisterItemCollection(edmItemCollection); Perspective perspective = new ModelPerspective(workspace); // Since we compile lambda expression and generate variables from the function parameter definitions, // the returned DbLambda will contain variable types that match function parameter types. var functionBody = CqlQuery.CompileQueryCommandLambda( functionDefinition, perspective, null /* use default parser options */, null /* parameters */, functionParameters.Select(pInfo => pInfo.TypeUsage.Variable(pInfo.Name))); Debug.Assert(functionBody != null, "functionBody != null"); return functionBody; }
public IEnumerable<KnownAssemblyEntry> GetEntries(object loaderCookie, EdmItemCollection itemCollection) { return _assemblies.Values.Where(e => e.HaveSeenInCompatibleContext(loaderCookie, itemCollection)); }
ComputeConstantDomainSetsForSlotsInUpdateViews(IEnumerable<Cell> cells, EdmItemCollection edmItemCollection) { Dictionary<MemberPath, CellConstantSet> updateDomainMap = new Dictionary<MemberPath, CellConstantSet>(MemberPath.EqualityComparer); foreach (Cell cell in cells) { CellQuery cQuery = cell.CQuery; CellQuery sQuery = cell.SQuery; foreach (MemberProjectedSlot sSlot in sQuery.GetConjunctsFromWhereClause().Select(oneOfConst => oneOfConst.RestrictedMemberSlot)) { // obtain initial slot domain and restrict it if the slot has conditions CellConstantSet restrictedDomain; bool wasDomainRestricted = GetRestrictedOrUnrestrictedDomain(sSlot, sQuery, edmItemCollection, out restrictedDomain); // Suppose that we have a cell: // Proj(ID, A) WHERE(A=5) FROM E = Proj(ID, B) FROM T // In the above cell, B on the S-side is 5 and we add that to its range. But if B had a restriction, // we do not add 5. Note that do we not have a problem w.r.t. possibleValues since if A=5 and B=1, we have an // empty cell -- we should catch that as an error. If A = 5 and B = 5 is present then restrictedDomain // and domainValues are the same // if no restriction on the S-side and the slot is projected then take the domain from the C-side if (!wasDomainRestricted) { int projectedPosition = sQuery.GetProjectedPosition(sSlot); if (projectedPosition >= 0) { // get the domain of the respective C-side slot MemberProjectedSlot cSlot = cQuery.ProjectedSlotAt(projectedPosition) as MemberProjectedSlot; Debug.Assert(cSlot != null, "Assuming constants are not projected"); wasDomainRestricted = GetRestrictedOrUnrestrictedDomain(cSlot, cQuery, edmItemCollection, out restrictedDomain); if (!wasDomainRestricted) { continue; } } } // Add the default value to the domain MemberPath sSlotMemberPath = sSlot.MemberPath; Constant defaultValue; if (TryGetDefaultValueForMemberPath(sSlotMemberPath, out defaultValue)) { restrictedDomain.Add(defaultValue); } // add all constants appearing in the domain to sDomainMap CellConstantSet sSlotDomain; if (!updateDomainMap.TryGetValue(sSlotMemberPath, out sSlotDomain)) { updateDomainMap[sSlotMemberPath] = restrictedDomain; } else { sSlotDomain.AddRange(restrictedDomain); } } } return updateDomainMap; }
//True = domain is restricted, False = domain is not restricted (because there is no condition) private static bool GetRestrictedOrUnrestrictedDomain(MemberProjectedSlot slot, CellQuery cellQuery, EdmItemCollection edmItemCollection, out CellConstantSet domain) { CellConstantSet domainValues = DeriveDomainFromMemberPath(slot.MemberPath, edmItemCollection, true /* leaveDomainUnbounded */); //Note, out domain is set even in the case where method call returns false return TryGetDomainRestrictedByWhereClause(domainValues, slot, cellQuery, out domain); }
ComputeConstantDomainSetsForSlotsInQueryViews(IEnumerable<Cell> cells, EdmItemCollection edmItemCollection, bool isValidationEnabled) { Dictionary<MemberPath, CellConstantSet> cDomainMap = new Dictionary<MemberPath, CellConstantSet>(MemberPath.EqualityComparer); foreach (Cell cell in cells) { CellQuery cQuery = cell.CQuery; // Go through the conjuncts to get the constants (e.g., we // just don't want to NULL, NOT(NULL). We want to say that // the possible values are NULL, 4, NOT(NULL, 4) foreach (MemberRestriction restriction in cQuery.GetConjunctsFromWhereClause()) { MemberProjectedSlot slot = restriction.RestrictedMemberSlot; CellConstantSet cDomain = DeriveDomainFromMemberPath(slot.MemberPath, edmItemCollection, isValidationEnabled); // Now we add the domain of oneConst into this //Isnull=true and Isnull=false conditions should not contribute to a member's domain cDomain.AddRange(restriction.Domain.Values.Where(c => !(c.Equals(Constant.Null) || c.Equals(Constant.NotNull)))); CellConstantSet values; bool found = cDomainMap.TryGetValue(slot.MemberPath, out values); if (!found) { cDomainMap[slot.MemberPath] = cDomain; } else { values.AddRange(cDomain); } } } return cDomainMap; }
// effects: Given a type, determines all possible values that can be created from Metadata private static CellConstantSet DeriveDomainFromType(EdmType type, EdmItemCollection edmItemCollection, bool leaveDomainUnbounded) { CellConstantSet domain = null; if (Helper.IsScalarType(type)) { // Get the domain for scalars -- for booleans, we special case. if (MetadataHelper.HasDiscreteDomain(type)) { Debug.Assert(Helper.AsPrimitive(type).PrimitiveTypeKind == PrimitiveTypeKind.Boolean, "Only boolean type has discrete domain."); // Closed domain domain = new Set<Constant>(CreateList(true, false), Constant.EqualityComparer); } else { // Unbounded domain domain = new Set<Constant>(Constant.EqualityComparer); if (leaveDomainUnbounded) { domain.Add(Constant.NotNull); } } } else //Type Constants - Domain is all possible concrete subtypes { Debug.Assert(Helper.IsEntityType(type) || Helper.IsComplexType(type) || Helper.IsRefType(type) || Helper.IsAssociationType(type)); // Treat ref types as their referenced entity types if (Helper.IsRefType(type)) { type = ((RefType)type).ElementType; } List<Constant> types = new List<Constant>(); foreach (EdmType derivedType in MetadataHelper.GetTypeAndSubtypesOf(type, edmItemCollection, false /*includeAbstractTypes*/)) { TypeConstant derivedTypeConstant = new TypeConstant(derivedType); types.Add(derivedTypeConstant); } domain = new Set<Constant>(types, Constant.EqualityComparer); } Debug.Assert(domain != null, "Domain not set up for some type"); return domain; }
// effects: Given a member, determines all possible values that can be created from Metadata internal static CellConstantSet DeriveDomainFromMemberPath(MemberPath memberPath, EdmItemCollection edmItemCollection, bool leaveDomainUnbounded) { CellConstantSet domain = DeriveDomainFromType(memberPath.EdmType, edmItemCollection, leaveDomainUnbounded); if (memberPath.IsNullable) { domain.Add(Constant.Null); } return domain; }
// effects: Creates a map with all the condition member constants // from extentCells. viewtarget determines whether the view is an // update or query view internal MemberDomainMap(ViewTarget viewTarget, bool isValidationEnabled, IEnumerable<Cell> extentCells, EdmItemCollection edmItemCollection, ConfigViewGenerator config, Dictionary<EntityType, Set<EntityType>> inheritanceGraph) { m_conditionDomainMap = new Dictionary<MemberPath, CellConstantSet>(MemberPath.EqualityComparer); m_edmItemCollection = edmItemCollection; Dictionary<MemberPath, CellConstantSet> domainMap = null; if (viewTarget == ViewTarget.UpdateView) { domainMap = Domain.ComputeConstantDomainSetsForSlotsInUpdateViews(extentCells, m_edmItemCollection); } else { domainMap = Domain.ComputeConstantDomainSetsForSlotsInQueryViews(extentCells, m_edmItemCollection, isValidationEnabled); } foreach (Cell cell in extentCells) { CellQuery cellQuery = cell.GetLeftQuery(viewTarget); // Get the atoms from cellQuery and only keep the ones that // are condition members foreach (MemberRestriction condition in cellQuery.GetConjunctsFromWhereClause()) { // Note: TypeConditions are created using OneOfTypeConst and // scalars are created using OneOfScalarConst MemberPath memberPath = condition.RestrictedMemberSlot.MemberPath; Debug.Assert(condition is ScalarRestriction || condition is TypeRestriction, "Unexpected restriction"); // Take the narrowed domain from domainMap, if any CellConstantSet domainValues; if (!domainMap.TryGetValue(memberPath, out domainValues)) { domainValues = Domain.DeriveDomainFromMemberPath(memberPath, edmItemCollection, isValidationEnabled); } //Don't count conditions that are satisfied through IsNull=false if (!domainValues.Contains(Constant.Null)) { //multiple values of condition represent disjunction in conditions (not currently supported) // if there is any condition constant that is NotNull if (condition.Domain.Values.All(conditionConstant => (conditionConstant.Equals(Constant.NotNull)))) { continue; } //else there is atleast one condition value that is allowed, continue view generation } //------------------------------------------ //| Nullable | IsNull | Test case | //| T | T | T | //| T | F | T | //| F | T | F | //| F | F | T | //------------------------------------------ //IsNull condition on a member that is non nullable is an invalid condition if (domainValues.Count <= 0 || (!domainValues.Contains(Constant.Null) && condition.Domain.Values.Contains(Constant.Null))) { string message = System.Data.Entity.Strings.ViewGen_InvalidCondition(memberPath.PathToString(false)); ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.InvalidCondition, message, cell, String.Empty); ExceptionHelpers.ThrowMappingException(record, config); } if (memberPath.IsAlwaysDefined(inheritanceGraph) == false) { domainValues.Add(Constant.Undefined); } AddToDomainMap(memberPath, domainValues); } } // Fill up the domains for the remaining slots as well m_nonConditionDomainMap = new Dictionary<MemberPath, CellConstantSet>(MemberPath.EqualityComparer); foreach (Cell cell in extentCells) { CellQuery cellQuery = cell.GetLeftQuery(viewTarget); // Get the atoms from cellQuery and only keep the ones that // are condition members foreach (MemberProjectedSlot slot in cellQuery.GetAllQuerySlots()) { MemberPath member = slot.MemberPath; if (m_conditionDomainMap.ContainsKey(member) == false && m_nonConditionDomainMap.ContainsKey(member) == false) { CellConstantSet memberSet = Domain.DeriveDomainFromMemberPath(member, m_edmItemCollection, true /* Regardless of validation, leave the domain unbounded because this is not a condition member */); if (member.IsAlwaysDefined(inheritanceGraph) == false) { // nonConditionMember may belong to subclass memberSet.Add(Constant.Undefined); } memberSet = Domain.ExpandNegationsInDomain(memberSet, memberSet); m_nonConditionDomainMap.Add(member, new CellConstantSetInfo(memberSet, slot)); } } } }
private static bool LoadAssemblyFromCache(ObjectItemCollection objectItemCollection, Assembly assembly, bool loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action <String> logLoadMessage) { // Check if its loaded in the cache - if the call is for loading referenced assemblies, make sure that all referenced // assemblies are also loaded KnownAssemblyEntry entry; if (objectItemCollection._knownAssemblies.TryGetKnownAssembly(assembly, objectItemCollection._loaderCookie, edmItemCollection, out entry)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false) { // don't say we loaded anything, unless we actually did before return(entry.CacheEntry.TypesInAssembly.Count != 0); } else if (entry.ReferencedAssembliesAreLoaded == true) { // this assembly was part of a all hands reference search return(true); } } lock (objectItemCollection.LoadAssemblyLock) { // Check after acquiring the lock, since the known assemblies might have got modified // Check if the assembly is already loaded. The reason we need to check if the assembly is already loaded, is that if (objectItemCollection._knownAssemblies.TryGetKnownAssembly(assembly, objectItemCollection._loaderCookie, edmItemCollection, out entry)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false || entry.ReferencedAssembliesAreLoaded == true) { return(true); } } Dictionary <string, EdmType> typesInLoading; List <EdmItemError> errors; KnownAssembliesSet knownAssemblies; if (objectItemCollection != null) { knownAssemblies = new KnownAssembliesSet(objectItemCollection._knownAssemblies); } else { knownAssemblies = new KnownAssembliesSet(); } // Load the assembly from the cache AssemblyCache.LoadAssembly(assembly, loadReferencedAssemblies, knownAssemblies, edmItemCollection, logLoadMessage, ref objectItemCollection._loaderCookie, out typesInLoading, out errors); // Throw if we have encountered errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } // We can encounter new assemblies, but they may not have any time in them if (typesInLoading.Count != 0) { // No errors, so go ahead and add the types and make them readonly // The existence of the loading lock tells us whether we should be thread safe or not, if we need // to be thread safe, then we need to use AtomicAddRange. We don't need to actually use the lock // because the caller should have done it already // Recheck the assemblies added, another list is created just to match up the collection type // taken in by AtomicAddRange() List <GlobalItem> globalItems = new List <GlobalItem>(); foreach (EdmType edmType in typesInLoading.Values) { globalItems.Add(edmType); string cspaceTypeName = ""; try { // Also populate the ocmapping information if (Helper.IsEntityType(edmType)) { cspaceTypeName = ((ClrEntityType)edmType).CSpaceTypeName; objectItemCollection._ocMapping.Add(cspaceTypeName, edmType); } else if (Helper.IsComplexType(edmType)) { cspaceTypeName = ((ClrComplexType)edmType).CSpaceTypeName; objectItemCollection._ocMapping.Add(cspaceTypeName, edmType); } else if (Helper.IsEnumType(edmType)) { cspaceTypeName = ((ClrEnumType)edmType).CSpaceTypeName; objectItemCollection._ocMapping.Add(cspaceTypeName, edmType); } // for the rest of the types like a relationship type, we do not have oc mapping, // so we don't keep that information } catch (ArgumentException e) { throw new MappingException(Strings.Mapping_CannotMapCLRTypeMultipleTimes(cspaceTypeName), e); } } // Create a new ObjectItemCollection and add all the global items to it. // Also copy all the existing items from the existing collection objectItemCollection.AtomicAddRange(globalItems); } // Update the value of known assemblies objectItemCollection._knownAssemblies = knownAssemblies; foreach (Assembly loadedAssembly in knownAssemblies.Assemblies) { CollectIfViewGenAssembly(loadedAssembly); } return(typesInLoading.Count != 0); } }
internal bool Contains(Assembly assembly, object loaderCookie, EdmItemCollection itemCollection) { KnownAssemblyEntry entry; return TryGetKnownAssembly(assembly, loaderCookie, itemCollection, out entry); }
private static void LoadStoreItemCollections(MetadataWorkspace workspace, DbConnection storeConnection, DbProviderFactory factory, DbConnectionOptions connectionOptions, EdmItemCollection edmItemCollection, MetadataArtifactLoader artifactLoader) { Debug.Assert(workspace.IsItemCollectionAlreadyRegistered(DataSpace.CSpace), "C-Space must be loaded before loading S or C-S space"); // The provider connection string is optional; if it has not been specified, // we pick up the store's connection string. // string providerConnectionString = connectionOptions[EntityConnectionStringBuilder.ProviderConnectionStringParameterName]; if (string.IsNullOrEmpty(providerConnectionString) && (storeConnection != null)) { providerConnectionString = storeConnection.ConnectionString; } // Build a string as the key and look up the MetadataCache for a match string storeCacheKey = CreateMetadataCacheKey(artifactLoader.GetOriginalPaths(), connectionOptions[EntityConnectionStringBuilder.ProviderParameterName], providerConnectionString); // Load store metadata. object entryToken; StorageMappingItemCollection mappingCollection = MetadataCache.GetOrCreateStoreAndMappingItemCollections(storeCacheKey, artifactLoader, edmItemCollection, out entryToken); workspace.RegisterItemCollection(mappingCollection.StoreItemCollection); workspace.RegisterItemCollection(mappingCollection); // Adding the store metadata entry token to the workspace workspace.AddMetadataEntryToken(entryToken); }
internal bool Contains(Assembly assembly, object loaderCookie, EdmItemCollection itemCollection) { KnownAssemblyEntry entry; return(TryGetKnownAssembly(assembly, loaderCookie, itemCollection, out entry)); }
/// <summary> /// Given the <paramref name="member"/> and one of its <paramref name="possibleType"/>s, determine the attributes that are relevant /// for this <paramref name="possibleType"/> and return a <see cref="MemberPath"/> signature corresponding to the <paramref name="possibleType"/> and the attributes. /// If <paramref name="needKeysOnly"/>=true, collect the key fields only. /// </summary> /// <param name="possibleType">the <paramref name="member"/>'s type or one of its subtypes</param> private static void GatherSignatureFromTypeStructuralMembers(MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, StructuralType possibleType, bool needKeysOnly) { // For each child member of this type, collect all the relevant scalar fields foreach (EdmMember structuralMember in Helper.GetAllStructuralMembers(possibleType)) { if (MetadataHelper.IsNonRefSimpleMember(structuralMember)) { if (!needKeysOnly || MetadataHelper.IsPartOfEntityTypeKey(structuralMember)) { MemberPath nonStructuredMember = new MemberPath(member, structuralMember); // Note: scalarMember's parent has already been added to the projectedSlotMap index.CreateIndex(nonStructuredMember); } } else { Debug.Assert(structuralMember.TypeUsage.EdmType is ComplexType || structuralMember.TypeUsage.EdmType is RefType, // for association ends "Only non-scalars expected - complex types, association ends"); MemberPath structuredMember = new MemberPath(member, structuralMember); GatherPartialSignature(index, edmItemCollection, structuredMember, // Only keys are required for entities referenced by association ends of an association. needKeysOnly || Helper.IsAssociationEndMember(structuralMember)); } } }
/// <summary> /// Starting at the <paramref name="member"/>, recursively generates <see cref="MemberPath"/>s for the fields embedded in it. /// </summary> /// <param name="member">corresponds to a value of an Entity or Complex or Association type</param> /// <param name="needKeysOnly">indicates whether we need to only collect members that are keys</param> private static void GatherPartialSignature(MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, bool needKeysOnly) { EdmType memberType = member.EdmType; ComplexType complexTypemember = memberType as ComplexType; Debug.Assert(complexTypemember != null || memberType is EntityType || // for entity sets memberType is AssociationType || // For association sets memberType is RefType, // for association ends "GatherPartialSignature can be called only for complex types, entity sets, association ends"); if (memberType is ComplexType && needKeysOnly) { // Check if the complex type needs to be traversed or not. If not, just return // from here. Else we need to continue to the code below. Right now, we do not // allow keys inside complex types return; } // Make sure that this member is in the slot map before any of its embedded objects. index.CreateIndex(member); // Consider each possible type value -- each type value conributes to a tuple in the result. // For that possible type, add all the type members into the signature. foreach (EdmType possibleType in MetadataHelper.GetTypeAndSubtypesOf(memberType, edmItemCollection, false /*includeAbstractTypes*/)) { StructuralType possibleStructuralType = possibleType as StructuralType; Debug.Assert(possibleStructuralType != null, "Non-structural subtype?"); GatherSignatureFromTypeStructuralMembers(index, edmItemCollection, member, possibleStructuralType, needKeysOnly); } }
// effects: Fixes the domains of variables in this as specified in FixEnumerableDomains private static void ReduceEnumerableDomainToEnumeratedValues(ViewTarget target, Dictionary<MemberPath, CellConstantSet> domainMap, ConfigViewGenerator config, EdmItemCollection edmItemCollection) { foreach (MemberPath member in domainMap.Keys) { if (MetadataHelper.HasDiscreteDomain(member.EdmType) == false) { continue; } CellConstantSet domain = Domain.DeriveDomainFromMemberPath(member, edmItemCollection, true /* leaveDomainUnbounded */); CellConstantSet extra = domainMap[member].Difference(domain); extra.Remove(Constant.Undefined); if (extra.Count > 0) { // domainMap has extra members -- we should get rid of them if (config.IsNormalTracing) { Helpers.FormatTraceLine("Changed domain of {0} from {1} - subtract {2}", member, domainMap[member], extra); } domainMap[member].Subtract(extra); } } }
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] //For EdmItemCollection constructor call. //Since we pass in empty collection for paths, we do not have any resource exposure here. private IList<EdmSchemaError> InternalGenerateMetadata() { if (_modelEntityContainer != null) { _modelEntityContainer = null; _mappingLookups = null; _edmItemCollection = null; } LoadMethodSessionState session = new LoadMethodSessionState(); try { session.EdmItemCollection = new EdmItemCollection(); if (this.GenerateForeignKeyProperties && this._targetEntityFrameworkVersion < EntityFrameworkVersions.Version2) { session.AddError(Strings.UnableToGenerateForeignKeyPropertiesForV1, ModelBuilderErrorCode.UnableToGenerateForeignKeyPropertiesForV1, EdmSchemaErrorSeverity.Error, null); return session.Errors; } List<AssociationSet> storeAssociationSets = new List<AssociationSet>(); CollectAllFkProperties(session); EntityContainer modelEntityContainer = new EntityContainer(_modelEntityContainerName, DataSpace.CSpace); // create the EntityTypes and EntitySets, and save up the AssociationSets for later. foreach (EntitySetBase storeSet in _storeEntityContainer.BaseEntitySets) { switch (storeSet.BuiltInTypeKind) { case BuiltInTypeKind.AssociationSet: // save these, and create them after the EntityTypes and EntitySets have been created string errorMessage; if (this.GenerateForeignKeyProperties || !EntityStoreSchemaGenerator.IsFkPartiallyContainedInPK(((AssociationSet)storeSet).ElementType, out errorMessage)) { storeAssociationSets.Add((AssociationSet)storeSet); } else { session.AddError(errorMessage, ModelBuilderErrorCode.UnsupportedForeinKeyPattern, EdmSchemaErrorSeverity.Error, null); } break; case BuiltInTypeKind.EntitySet: EntitySet set = (EntitySet)storeSet; session.CandidateCollapsedAssociations.Add(set, new OneToOneMappingSerializer.CollapsedEntityAssociationSet(set)); break; default: // error throw EDesignUtil.MissingGenerationPatternForType(storeSet.BuiltInTypeKind); } } foreach (AssociationSet storeAssociationSet in storeAssociationSets) { SaveAssociationForCollapsedAssociationCandidate(session, storeAssociationSet); } Set<AssociationSet> associationSetsFromCollapseCandidateRejects = new Set<AssociationSet>(); IEnumerable<OneToOneMappingSerializer.CollapsedEntityAssociationSet> invalidCandidates = FindAllInvalidCollapsedAssociationCandidates(session); // now that we have gone through all of the association sets, foreach (OneToOneMappingSerializer.CollapsedEntityAssociationSet collapsed in invalidCandidates) { session.CandidateCollapsedAssociations.Remove(collapsed.EntitySet); // just create the entity set and save the association set to be added later EntitySet entitySet = CreateModelEntitySet(session, collapsed.EntitySet); modelEntityContainer.AddEntitySetBase(entitySet); associationSetsFromCollapseCandidateRejects.AddRange(collapsed.AssociationSets); } // create all the associations for the invalid collapsed entity association candidates foreach (AssociationSet storeAssociationSet in (IEnumerable<AssociationSet>)associationSetsFromCollapseCandidateRejects) { if (!IsAssociationPartOfCandidateCollapsedAssociation(session, storeAssociationSet)) { AssociationSet set = CreateModelAssociationSet(session, storeAssociationSet); modelEntityContainer.AddEntitySetBase(set); } } // save the set that needs to be created and mapped session.MappingLookups.CollapsedEntityAssociationSets.AddRange(session.CandidateCollapsedAssociations.Values); // do this in a seperate loop so we are sure all the necessary EntitySets have been created foreach (OneToOneMappingSerializer.CollapsedEntityAssociationSet collapsed in session.MappingLookups.CollapsedEntityAssociationSets) { AssociationSet set = CreateModelAssociationSet(session, collapsed); modelEntityContainer.AddEntitySetBase(set); } if (this._targetEntityFrameworkVersion >= EntityFrameworkVersions.Version2) { Debug.Assert(EntityFrameworkVersions.Latest == EntityFrameworkVersions.Version3, "Did you add a new framework version"); // add LazyLoadingEnabled=true to the EntityContainer MetadataProperty lazyLoadingAttribute = new MetadataProperty( DesignXmlConstants.EdmAnnotationNamespace + ":" + DesignXmlConstants.LazyLoadingEnabled, TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType( PrimitiveTypeKind.String), false, false), true); modelEntityContainer.AddMetadataProperties(new List<MetadataProperty>() { lazyLoadingAttribute }); this._hasAnnotationNamespace = true; } // Map store functions to function imports. MapFunctions(session, modelEntityContainer); if (!EntityStoreSchemaGenerator.HasErrorSeverityErrors(session.Errors)) { // add them to the collection so they will work if someone wants to use the collection foreach (EntityType type in session.MappingLookups.StoreEntityTypeToModelEntityType.Values) { type.SetReadOnly(); session.EdmItemCollection.AddInternal(type); } foreach (AssociationType type in session.MappingLookups.StoreAssociationTypeToModelAssociationType.Values) { type.SetReadOnly(); session.EdmItemCollection.AddInternal(type); } foreach (OneToOneMappingSerializer.CollapsedEntityAssociationSet set in session.MappingLookups.CollapsedEntityAssociationSets) { set.ModelAssociationSet.ElementType.SetReadOnly(); session.EdmItemCollection.AddInternal(set.ModelAssociationSet.ElementType); } modelEntityContainer.SetReadOnly(); session.EdmItemCollection.AddInternal(modelEntityContainer); _modelEntityContainer = modelEntityContainer; _mappingLookups = session.MappingLookups; _edmItemCollection = session.EdmItemCollection; } } catch (Exception e) { if (MetadataUtil.IsCatchableExceptionType(e)) { // an exception in the code is definitely an error string message = EDesignUtil.GetMessagesFromEntireExceptionChain(e); session.AddError(message, ModelBuilderErrorCode.UnknownError, EdmSchemaErrorSeverity.Error, e); } else { throw; } } return session.Errors; }
public IEnumerable <KnownAssemblyEntry> GetEntries(object loaderCookie, EdmItemCollection itemCollection) { return(_assemblies.Values.Where(e => e.HaveSeenInCompatibleContext(loaderCookie, itemCollection))); }