public override List <string> BuildSchema(string metadataContent) { var result = new List <string>(); #if no try { var modelDefinition = new ModelDefinition() { MetaData = metadataContent, Kind = "OData" }; var modelSchema = new ModelSchema(); var builder = new ODataModelBuilder(); builder.ModelDefinition = modelDefinition; builder.ModelSchema = modelSchema; result = builder.Build(); // https://github.com/OData/odata.net/blob/master/src/CodeGen/ODataT4CodeGenerator.ttinclude this.EdmModel = builder.EdmModel; this.ModelSchema = modelSchema; this.ModelDefinition = modelDefinition; } catch (Exception error) { result.Add(error.ToString()); } #endif return(result); }
public override ModelSchema GetModelSchema(MetaModelBuilder metaModelBuilder, ModelErrors errors) { var result = this.ModelSchema; if (result is null) { if (this._EdmxModel != null) { var builder = new EdmxModelSchemaBuilder(); result = new ModelSchema(); builder.Build(this._EdmxModel, result, metaModelBuilder, errors); #warning result.Freeze(); this.ModelSchema = result; } } return(result); }
public ModelScalarType BuildScalarType(EdmxModel edmxModel, ModelSchema modelSchema, CsdlScalarTypeModel scalarTypeModel, MetaModelBuilder metaModelBuilder, ModelErrors errors) { if (string.Equals(scalarTypeModel.Namespace, "Edm", StringComparison.Ordinal)) { return(null); } // #warning BuildScalarType - when does this happen? var name = scalarTypeModel.Name; var fullName = scalarTypeModel.FullName; ModelScalarType result = new ModelScalarType { Name = name, ExternalName = fullName }; modelSchema.ScalarTypes.Add(result); return(result); }
public void BuildAssociation(EdmxModel edmxModel, ModelSchema modelSchema, CsdlAssociationModel association, MetaModelBuilder metaModelBuilder, ModelErrors errors) { foreach (var associationEnd in association.AssociationEnd) { if (associationEnd.TypeModel is null) { if (!(associationEnd.TypeName is null)) { errors.AddErrorOrThrow($"{associationEnd.TypeName} not found.", $"{association.FullName} - {associationEnd.FullName}"); } continue; } //associationEnd.GetMultiplicity() //var roleName = associationEnd.RoleName; //associationEnd.TypeModel } var lstOneOptional = association.AssociationEnd.Where(end => end.GetMultiplicity() == MultiplicityKind.OneOptional).ToList(); var lstOne = association.AssociationEnd.Where(end => end.GetMultiplicity() == MultiplicityKind.One).ToList(); var lstMultiple = association.AssociationEnd.Where(end => end.GetMultiplicity() == MultiplicityKind.Multiple).ToList(); if ((lstOneOptional.Count == 1) && (lstMultiple.Count == 1)) { var masterEnd = lstOneOptional[0]; var foreignEnd = lstMultiple[0]; var lstMasterProperty = masterEnd.TypeModel.NavigationProperty.Where(np => np.FromRoleName == masterEnd.RoleName).ToList(); var lstForeignProperty = foreignEnd.TypeModel.NavigationProperty.Where(np => np.FromRoleName == foreignEnd.RoleName).ToList(); if ((lstMasterProperty.Count == 1) && (lstForeignProperty.Count == 1)) { //modelSchema.ComplexTypes.FindByKey2(lstMasterProperty[0]) //modelSchema.ComplexTypes.FindByKey2(lstMasterProperty[0].TypeModel.Nam) var result = metaModelBuilder.CreateModelRelation( association.Name, association.FullName, lstMasterProperty[0].ToRoleModel.TypeName, lstMasterProperty[0].Name, lstForeignProperty[0].ToRoleModel.TypeName, lstForeignProperty[0].Name ); modelSchema.Relations.Add(result); } } }
// GET: /<controller>/ public async Task <IActionResult> Index() { AuthenticationResult result = null; List <ModelSchema> schemaList = new List <ModelSchema>(); try { // Because we signed-in already in the WebApp, the userObjectId is known string userObjectID = (User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value; // Using ADAL.Net, get a bearer token to access the MRSDistComp Web APIs AuthenticationContext authContext = new AuthenticationContext(AzureAdOptions.Settings.CentralRegistryAuthority, new NaiveSessionCache(userObjectID, HttpContext.Session)); ClientCredential credential = new ClientCredential(AzureAdOptions.Settings.ClientId, AzureAdOptions.Settings.ClientSecret); result = await authContext.AcquireTokenAsync(AzureAdOptions.Settings.CentralRegistryResourceAppId, credential); // Retrieve the schemas list. HttpClient client = new HttpClient(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, AzureAdOptions.Settings.CentralRegistryBaseAddress + "/api/GetSchemas"); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); HttpContent content = new StringContent(JsonConvert.SerializeObject(new { schemaname = string.Empty }), System.Text.Encoding.UTF8, "application/json"); request.Content = content; HttpResponseMessage response = await client.SendAsync(request); // Return the schemas' in the view. if (response.IsSuccessStatusCode) { List <Dictionary <String, String> > responseElements = new List <Dictionary <String, String> >(); JsonSerializerSettings settings = new JsonSerializerSettings(); String responseString = await response.Content.ReadAsStringAsync(); JObject responseJObject = JObject.Parse(responseString); // This is based on the Web API JSON. List of lists of the Result. IList <JToken> rows = responseJObject["outputParameters"]["Result"].Children().ToList(); // serialize JSON results into .NET objects foreach (JToken row in rows) { foreach (JToken column in row) { ModelSchema schema = new ModelSchema(); schema.Name = column[1].ToString(); schema.Description = column[2].ToString(); schema.Version = column[3].ToString(); schema.SchemaJSON = column[4].ToString(); schemaList.Add(schema); } } return(View(schemaList)); } else { // // If the call failed with access denied, then drop the current access token from the cache, // and show the user an error indicating they might need to sign-in again. // if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized) { var cachedTokens = authContext.TokenCache.ReadItems().Where(a => a.Resource == AzureAdOptions.Settings.CentralRegistryResourceAppId); foreach (TokenCacheItem tci in cachedTokens) { authContext.TokenCache.DeleteItem(tci); } ViewBag.ErrorMessage = "UnexpectedError"; ModelSchema newModelSchema = new ModelSchema(); newModelSchema.Name = "(No data schemas exist in the system)"; schemaList.Add(newModelSchema); return(View(schemaList)); } } } catch (Exception ex) { if (HttpContext.Request.Query["reauth"] == "True") { // // Send an OpenID Connect sign-in request to get a new set of tokens. // If the user still has a valid session with Azure AD, they will not be prompted for their credentials. // The OpenID Connect middleware will return to this controller after the sign-in response has been handled. // return(new ChallengeResult(OpenIdConnectDefaults.AuthenticationScheme)); } // // The user needs to re-authorize. Show them a message to that effect. // ModelSchema newModelSchema = new ModelSchema(); newModelSchema.Name = "(Sign-in required to view data schemas.)"; schemaList.Add(newModelSchema); ViewBag.ErrorMessage = "AuthorizationRequired" + ex.Message; return(View(schemaList)); } // // If the call failed for any other reason, show the user an error. // return(View("Error")); }
public async Task <ActionResult> Index(string name, string description, string schemajson) { if (ModelState.IsValid) { // // Retrieve the user's tenantID and access token // AuthenticationResult result = null; List <ModelSchema> schemaList = new List <ModelSchema>(); try { string userObjectID = (User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value; AuthenticationContext authContext = new AuthenticationContext(AzureAdOptions.Settings.CentralRegistryAuthority, new NaiveSessionCache(userObjectID, HttpContext.Session)); ClientCredential credential = new ClientCredential(AzureAdOptions.Settings.ClientId, AzureAdOptions.Settings.ClientSecret); result = await authContext.AcquireTokenAsync(AzureAdOptions.Settings.CentralRegistryResourceAppId, credential); if (string.IsNullOrEmpty(description)) { description = name; } // Forms encode schema record, to POST to the MRSDistComp Web API. HttpContent content = new StringContent(JsonConvert.SerializeObject(new { schemaname = name, schemadesc = description, schema = schemajson, broadcast = true }), System.Text.Encoding.UTF8, "application/json"); // // Add new data schema to the data catalog. // HttpClient client = new HttpClient(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, AzureAdOptions.Settings.CentralRegistryBaseAddress + "/api/RegisterSchema"); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); request.Content = content; HttpResponseMessage response = await client.SendAsync(request); // // Return the view. // if (response.IsSuccessStatusCode) { return(RedirectToAction("Index")); } else { // // If the call failed with access denied, then drop the current access token from the cache, // and show the user an error indicating they might need to sign-in again. // if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized) { var cachedTokens = authContext.TokenCache.ReadItems().Where(a => a.Resource == AzureAdOptions.Settings.CentralRegistryResourceAppId); foreach (TokenCacheItem tci in cachedTokens) { authContext.TokenCache.DeleteItem(tci); } ViewBag.ErrorMessage = "UnexpectedError"; ModelSchema newModelSchema = new ModelSchema(); newModelSchema.Name = "(Sign-in required to view data catalog.)"; schemaList.Add(newModelSchema); return(View(newModelSchema)); } } } catch { // // The user needs to re-authorize. Show them a message to that effect. // ModelSchema newModelSchema = new ModelSchema(); newModelSchema.Name = "(No schemas exist in the data catalog)"; schemaList.Add(newModelSchema); ViewBag.ErrorMessage = "AuthorizationRequired"; return(View(schemaList)); } // // If the call failed for any other reason, show the user an error. // return(View("Error")); } return(View("Error")); }
public ModelSchema ConvertSchema(IEdmModel edmModel) { var entityContainers = edmModel.EntityContainers().ToArray(); var defaultEntityContainer = entityContainers.First(_ => edmModel.IsDefaultEntityContainer(_)); var entitySets = defaultEntityContainer.EntitySets().ToArray(); var modelSchema = new ModelSchema(); var modelEntityRoot = new ModelEntity(); var complexTypeRoot = new ModelComplexType(); // TODO: add ns modelEntityRoot.Name = new ModelEntityName(defaultEntityContainer.Namespace, null, defaultEntityContainer.Name); complexTypeRoot.Name = new ModelEntityName(defaultEntityContainer.Namespace, null, defaultEntityContainer.Name); modelEntityRoot.EntityType = complexTypeRoot; modelSchema.Entities.Add(modelEntityRoot); modelEntityRoot.Kind = ModelEntityKind.Container; foreach (var entitySet in entitySets) { var elementType = entitySet.ElementType; var complexType = new ModelComplexType(); var modelEntity = new ModelEntity(); complexType.Name = new ModelEntityName(elementType.Namespace, null, elementType.Name); modelEntity.Name = new ModelEntityName(null, null, entitySet.Name); modelEntity.EntityType = complexType; modelEntity.Kind = ModelEntityKind.EntitySet; modelSchema.ComplexTypes.Add(complexType); modelSchema.Entities.Add(modelEntity); var declaredStructuralProperties = elementType.DeclaredStructuralProperties().ToArray(); foreach (var declaredStructuralProperty in declaredStructuralProperties) { var declaredStructuralPropertyType = declaredStructuralProperty.Type; var declaredStructuralPropertyTypeDefinition = declaredStructuralPropertyType.Definition; var modelProperty = new ModelProperty(); modelProperty.Name = declaredStructuralProperty.Name; if (declaredStructuralPropertyType.IsPrimitive()) { var modelPropertyType = new ModelScalarType(); var vas = declaredStructuralProperty.VocabularyAnnotations(edmModel).ToArray(); if (declaredStructuralPropertyTypeDefinition is IEdmSchemaElement edmSchemaElement) { modelPropertyType.Name = new ModelEntityName(edmSchemaElement.Namespace, null, edmSchemaElement.Name); } else { modelPropertyType.Name = new ModelEntityName(null, null, declaredStructuralPropertyType.FullName()); } modelPropertyType.IsNullable = declaredStructuralPropertyType.IsNullable; modelProperty.Type = modelPropertyType; } else { throw new NotImplementedException(); } complexType.Properties.Add(modelProperty); } //complexType.Properties } foreach (var entitySet in entitySets) { var entityName = new ModelEntityName(null, null, entitySet.Name); var modelEntity = modelSchema.Entities.FirstOrDefault(_ => _.Name == entityName); var navigationTargets = entitySet.NavigationTargets.ToArray(); foreach (var navigationTarget in navigationTargets) { // var navigationProperty = navigationTarget.NavigationProperty; if (navigationProperty is IEdmNavigationProperty edmNavigationProperty) { if (navigationProperty.ContainsTarget) { } } var navigationPropertyPartner = navigationProperty.Partner; var targetEntitySet = navigationTarget.TargetEntitySet; // var naviFromProperties = navigationProperty.DependentProperties?.ToArray(); var naviToProperties = navigationPropertyPartner.DependentProperties?.ToArray(); var modelRelation = new ModelRelation(); var targetEntityName = new ModelEntityName(null, null, targetEntitySet.Name); var targetModelEntity = modelSchema.Entities.FirstOrDefault(_ => _.Name == targetEntityName); modelRelation.Name = navigationTarget.TargetEntitySet.Name; //modelRelation.MasterEntity = //modelRelation.ForeignEntity = targetModelEntity; modelRelation.ForeignName = targetEntityName; modelSchema.Relations.Add(modelRelation); } } return(modelSchema); }
public ModelComplexType BuildComplexTypeNavigationProperty(EdmxModel edmxModel, ModelSchema modelSchema, CsdlEntityTypeModel entityTypeModel, MetaModelBuilder metaModelBuilder, ModelErrors errors) { ModelComplexType result = null; var entityTypeModelName = entityTypeModel.Name; var entityTypeModelFullName = entityTypeModel.FullName; var lstFound = modelSchema.ComplexTypes.FindByKey2(entityTypeModelFullName ?? entityTypeModelName); if (lstFound.Count == 1) { result = lstFound[0]; } else if (lstFound.Count > 1) { errors.AddErrorOrThrow(new ModelErrorInfo($"found key {entityTypeModelFullName ?? entityTypeModelName} #{lstFound.Count} times.", entityTypeModelFullName ?? entityTypeModelName)); result = lstFound[0]; } else { result = BuildComplexType(edmxModel, modelSchema, entityTypeModel, metaModelBuilder, errors); } if (result == null) { return(null); } foreach (var navigationProperty in entityTypeModel.NavigationProperty) { if (navigationProperty.RelationshipName is null) { //navigationProperty.Name //navigationProperty.TypeModel //navigationProperty.PartnerModel throw new NotImplementedException("v4 NavigationProperty"); } else { // v3 //if (navigationProperty.FromRoleModel is null) { //} else { //} if (navigationProperty.ToRoleModel is null) { } else { var toModel = navigationProperty.ToRoleModel.TypeModel; var lstToComplexTypes = modelSchema.ComplexTypes.FindByKey2(toModel.FullName); if (lstToComplexTypes.Count == 1) { var toComplexType = lstToComplexTypes[0]; var navigationPropertyExternalName = navigationProperty.Name; #warning magic needed here var navigationPropertyName = navigationPropertyExternalName; bool isCollection = false; bool isOptional = false; switch (navigationProperty.ToRoleModel.GetMultiplicity()) { case MultiplicityKind.Unknown: break; case MultiplicityKind.OneOptional: isOptional = true; break; case MultiplicityKind.One: break; case MultiplicityKind.Multiple: isCollection = true; break; default: break; } var modelNavigationProperty = result.CreateNavigationProperty( navigationPropertyName, navigationPropertyExternalName, toComplexType, isOptional, isCollection ); } } } } /* */ return(result); }
public ModelComplexType BuildComplexType(EdmxModel edmxModel, ModelSchema modelSchema, CsdlEntityTypeModel entityTypeModel, MetaModelBuilder metaModelBuilder, ModelErrors errors) { var entityTypeModelName = entityTypeModel.Name; var entityTypeModelFullName = entityTypeModel.FullName; var lstFound = modelSchema.ComplexTypes.FindByKey2(entityTypeModelFullName ?? entityTypeModelName); if (lstFound.Count == 1) { return(lstFound[0]); } else if (lstFound.Count > 1) { errors.AddErrorOrThrow(new ModelErrorInfo($"found key {entityTypeModelFullName ?? entityTypeModelName} #{lstFound.Count} times.", entityTypeModelFullName ?? entityTypeModelName)); return(lstFound[0]); } var modelComplexType = metaModelBuilder.CreateModelComplexType( entityTypeModelName, entityTypeModelFullName, errors); if (modelComplexType.Owner == null) { modelSchema.ComplexTypes.Add(modelComplexType); } foreach (var property in entityTypeModel.Property) { ModelScalarType modelScalarType = null; ModelScalarType suggestedType = property.SuggestType(metaModelBuilder); // TODO: thinkof EdmxModelBuilder Build ScalarType //if (property.ScalarType != null) { // property.ScalarType.FullName //} modelScalarType = metaModelBuilder.CreateModelScalarType( entityTypeModelName, entityTypeModelFullName, property.Name, null, property.TypeName, suggestedType, property.MaxLength, property.FixedLength, property.Nullable, property.Precision, property.Scale, errors ); var modelProperty = metaModelBuilder.CreateModelProperty( entityTypeModelName, entityTypeModelFullName, property.Name, null, errors ); if (modelProperty.Type == null) { modelProperty.Type = modelScalarType; } if (modelProperty.Owner == null) { modelComplexType.Properties.Add(modelProperty); } } var primaryKey = entityTypeModel.Keys; if (primaryKey.Count > 0) { var modelIndex = metaModelBuilder.CreateModelIndex( entityTypeModelName, entityTypeModelFullName, "PrimaryKey", null, errors ); modelIndex.IsPrimaryKey = true; if (modelIndex.Owner == null) { modelComplexType.Indexes.Add(modelIndex); } foreach (var keyModel in entityTypeModel.Keys) { var modelIndexProperty = metaModelBuilder.CreateModelIndexProperty( entityTypeModelName, entityTypeModelFullName, modelIndex.Name, modelIndex.ExternalName, keyModel.Name, null, //keyModel.Property, errors ); if (modelIndexProperty.Owner == null) { modelIndex.Properties.Add(modelIndexProperty); } } } return(modelComplexType); }
public ModelSchema Build( EdmxModel edmxModel, ModelSchema modelSchema, MetaModelBuilder metaModelBuilder, ModelErrors errors) { if (modelSchema == null) { modelSchema = new ModelSchema(); } //if (metaMappingSchema == null) { metaMappingSchema = new MetaMappingSchema(); } if (metaModelBuilder == null) { metaModelBuilder = new MetaModelBuilder(); } if (!edmxModel.IsFrozen()) { edmxModel.AddCoreSchemaIfNeeded(errors); edmxModel.Freeze(); } var defaultEntityContainers = edmxModel.DataServices.SelectMany(_ => _.EntityContainer).Where(_ => _.IsDefaultEntityContainer).ToList(); if (defaultEntityContainers.Count != 1) { defaultEntityContainers = edmxModel.DataServices.SelectMany(_ => _.EntityContainer).ToList(); } if (defaultEntityContainers.Count != 1) { errors.AddErrorOrThrow($"DefaultEntityContainers #{defaultEntityContainers.Count} found.", "model"); return(modelSchema); } var defaultEntityContainer = defaultEntityContainers[0]; edmxModel.ResolveNames(errors); if (errors.HasErrors()) { return(modelSchema); } foreach (var dataServices in edmxModel.DataServices) { foreach (var scalarTypeModel in dataServices.ScalarTypeModel) { this.BuildScalarType(edmxModel, modelSchema, scalarTypeModel, metaModelBuilder, errors); } } foreach (var dataServices in edmxModel.DataServices) { foreach (var entityTypeModel in dataServices.EntityType) { this.BuildComplexType(edmxModel, modelSchema, entityTypeModel, metaModelBuilder, errors); } } foreach (var dataServices in edmxModel.DataServices) { foreach (var entityTypeModel in dataServices.EntityType) { this.BuildComplexTypeNavigationProperty(edmxModel, modelSchema, entityTypeModel, metaModelBuilder, errors); } } foreach (var dataServices in edmxModel.DataServices) { foreach (var association in dataServices.Association) { this.BuildAssociation(edmxModel, modelSchema, association, metaModelBuilder, errors); } } //foreach (var dataServices in edmxModel.DataServices) { // foreach (var entityContainer in dataServices.EntityContainer) { // if (entityContainer.IsDefaultEntityContainer) { continue; } // } //} foreach (var entitySet in defaultEntityContainer.EntitySet) { var entityTypeModel = entitySet.EntityTypeModel; if (entityTypeModel == null) { errors.AddErrorOrThrow("entitySet.EntityTypeModel not found", entitySet.Name); } else { var entityTypeModelName = entityTypeModel.Name; var entityTypeModelFullName = entityTypeModel.FullName; var modelComplexType = this.BuildComplexType(edmxModel, modelSchema, entityTypeModel, metaModelBuilder, errors); var entitySetName = entitySet.Name; var modelEntity = metaModelBuilder.CreateModelEntity( entitySetName, ModelEntityKind.EntitySet, errors); if (modelEntity.Owner == null) { modelSchema.Entities.Add(modelEntity); } if (modelComplexType is null) { errors.AddErrorOrThrow($"{entityTypeModelFullName ?? entityTypeModelName} not found", entitySet.Name); } else { modelEntity.EntityType = modelComplexType; } } } //foreach (var associationSet in defaultEntityContainer.AssociationSet) { // foreach (var end in associationSet.End) { // if (!(end.EntitySetModel is null)) { // var roleName = d.RoleName; // } // } //} return(modelSchema); }
public void BuildModelSqlDatabase( ModelSchema modelSchema, ModelSqlDatabase modelDatabase, MetaModelBuilder metaModelBuilder, ModelErrors errors) { foreach (var modelEntitySource in modelSchema.Entities) { var modelEntityTypeSource = modelEntitySource.EntityType; if (modelEntityTypeSource is null) { #warning SOON add error } else { var tableNameTarget = modelEntitySource.ExternalName ?? modelEntitySource.Name; var sqlTableNameTarget = SqlName.Parse(tableNameTarget, ObjectLevel.Object); var tableTarget = ModelSqlTable.Ensure(modelDatabase, sqlTableNameTarget); foreach (var property in modelEntityTypeSource.Properties) { var sqlColumnNameTarget = SqlName.Parse(property.ExternalName ?? property.Name, ObjectLevel.Object); ModelSqlColumn column = ModelSqlColumn.Ensure(tableTarget, sqlColumnNameTarget.Name); if (property.Type is ModelScalarType propertyScalarType) { var clrTypeSource = property.GetClrType(); var typeName = propertyScalarType.Name; #warning TODO SOON better Scalar Type Handling this is ugly if (!(clrTypeSource is null)) { var innerNullableClrTypeSource = ((clrTypeSource.IsValueType) ? Nullable.GetUnderlyingType(clrTypeSource) : null) ?? clrTypeSource; if (!(column.SqlType is null)) { var clrScalarTypeTarget = column.SqlType.GetScalarType()?.GetClrType(); var innerNullableClrScalarTypeTarget = ((clrScalarTypeTarget.IsValueType) ? Nullable.GetUnderlyingType(clrScalarTypeTarget) : null) ?? clrScalarTypeTarget; if (!(clrScalarTypeTarget is null) && (clrScalarTypeTarget.IsAssignableFrom(innerNullableClrScalarTypeTarget))) { // ok } else { column.SqlType = null; } } } if (column.SqlType is null) { var sqlTypeTarget = modelDatabase.Types.GetValueOrDefault(SqlName.Parse(typeName, ObjectLevel.Object)); if (!(sqlTypeTarget is null)) { column.SqlType = sqlTypeTarget; } else { if (!(clrTypeSource is null)) { var innerNullableClrTypeSource = ((clrTypeSource.IsValueType) ? Nullable.GetUnderlyingType(clrTypeSource) : null) ?? clrTypeSource; var lstTypes = new List <ModelSqlType>(); foreach (var type in modelDatabase.Types) { var clrScalarTypeTarget = type.GetScalarType()?.GetClrType(); if (clrScalarTypeTarget is null) { continue; } var innerNullableClrScalarTypeTarget = ((clrScalarTypeTarget.IsValueType) ? Nullable.GetUnderlyingType(clrScalarTypeTarget) : null) ?? clrScalarTypeTarget; if (innerNullableClrTypeSource.Equals(innerNullableClrScalarTypeTarget)) { lstTypes.Add(type); } else if (innerNullableClrTypeSource.IsAssignableFrom(innerNullableClrScalarTypeTarget)) { lstTypes.Add(type); } } if (lstTypes.Count == 1) { sqlTypeTarget = lstTypes[0]; column.SqlType = sqlTypeTarget; } else if (lstTypes.Count > 1) { sqlTypeTarget = null; if (clrTypeSource == typeof(string)) { sqlTypeTarget = modelDatabase.Types.GetValueOrDefault(SqlName.Parse("[sys].[nvarchar]", ObjectLevel.Object)); } else if (clrTypeSource == typeof(DateTime)) { sqlTypeTarget = modelDatabase.Types.GetValueOrDefault(SqlName.Parse("[sys].[datetime2]", ObjectLevel.Object)); } else if (clrTypeSource == typeof(DateTime?)) { sqlTypeTarget = modelDatabase.Types.GetValueOrDefault(SqlName.Parse("[sys].[datetime2]", ObjectLevel.Object)); } if (sqlTypeTarget is null) { sqlTypeTarget = lstTypes[0]; } column.SqlType = sqlTypeTarget; } else { errors.Add(new ModelErrorInfo($"Unknown mapping for {typeName} - {clrTypeSource}.", column.NameSql)); sqlTypeTarget = modelDatabase.Types.GetValueOrDefault(SqlName.Parse("[sys].[nvarchar]", ObjectLevel.Object)); column.SqlType = sqlTypeTarget; } } } sqlTypeTarget = column.SqlType; if (sqlTypeTarget is null) { errors.Add(new ModelErrorInfo($"column.SqlType is null.", column.NameSql)); } else { sqlTypeTarget.Nullable = propertyScalarType.Nullable.GetValueOrDefault(true); if (propertyScalarType.MaxLength.HasValue) { sqlTypeTarget.MaxLength = propertyScalarType.MaxLength; } else { //if (typeof(string).Equals(sqlTypeTarget.GetScalarType().GetClrType())) { // sqlTypeTarget.MaxLength = -1; //} } } } // if (column.SqlType is null) }
public void BuildModelSchema( ModelSqlDatabase modelDatabase, ModelSchema modelSchema, MetaModelBuilder metaModelBuilder, ModelErrors errors) { if (modelSchema == null) { modelSchema = new ModelSchema(); } if (metaModelBuilder == null) { metaModelBuilder = new MetaModelBuilder(); } // modelDatabase.Freeze(); foreach (var table in modelDatabase.Tables) { var entityTypeModelName = table.Name.GetQFullName(null, 2); var entityTypeModelFullName = table.Name.GetQFullName("[", 2); var modelComplexType = metaModelBuilder.CreateModelComplexType( entityTypeModelName, entityTypeModelFullName, errors); if (modelComplexType.Owner == null) { modelSchema.ComplexTypes.Add(modelComplexType); } foreach (var column in table.Columns) { ModelScalarType modelScalarType = null; ModelScalarType suggestedType = column.SuggestType(metaModelBuilder); modelScalarType = metaModelBuilder.CreateModelScalarType( entityTypeModelName, entityTypeModelFullName, column.Name.GetQName(), null, column.SqlType.Name.GetQFullName(), suggestedType, column.MaxLength, column.FixedLength, column.Nullable, column.Precision, column.Scale, errors ); var columnName = column.Name.GetQFullName(null, 1); var columnExternalName = column.Name.GetQFullName("[", 1); var modelProperty = metaModelBuilder.CreateModelProperty( entityTypeModelName, entityTypeModelFullName, columnName, columnExternalName, errors ); if (modelProperty.Type == null) { modelProperty.Type = modelScalarType; } if (modelProperty.Owner == null) { modelComplexType.Properties.Add(modelProperty); } } var tableIndexes = table.Indexes.ToList(); var lstPrimaryIndex = tableIndexes.Where(sqlIndex => sqlIndex.IsPrimaryKey).ToList(); var primaryIndex = lstPrimaryIndex.FirstOrDefault(); if (lstPrimaryIndex.Count == 1) { //var sqlIndex = lstPrimaryIndex[0]; // OK } else if (lstPrimaryIndex.Count > 1) { errors.AddErrorOrThrow($"More than one ({lstPrimaryIndex.Count}) primary key.", table.NameSql); } else { #warning think of no primary key } foreach (var sqlIndex in tableIndexes) { #warning have indexes a schema?? var modelIndex = metaModelBuilder.CreateModelIndex(entityTypeModelName, entityTypeModelFullName, sqlIndex.Name.Name, sqlIndex.Name.Name, errors); //modelIndex.IsPrimaryKey = sqlIndex.IsPrimaryKey; modelIndex.IsPrimaryKey = ReferenceEquals(sqlIndex, primaryIndex); modelComplexType.Indexes.Add(modelIndex); foreach (var column in sqlIndex.Columns) { var modelIndexProperty = metaModelBuilder.CreateModelIndexProperty( entityTypeModelName, entityTypeModelFullName, sqlIndex.Name.Name, sqlIndex.Name.Name, column.Name.Name, null, errors ); modelIndex.Properties.Add(modelIndexProperty); } } var entitySetName = table.Name.GetQFullName(null, 2); var modelEntity = metaModelBuilder.CreateModelEntity( entitySetName, ModelEntityKind.EntitySet, errors); if (modelEntity.Owner == null) { modelSchema.Entities.Add(modelEntity); } modelEntity.EntityType = modelComplexType; } }