Service OData sans écrire de code


L'un des aspects les plus importants du développement logiciel est le prototypage rapide. La plupart des services nécessitent au moins certaines opérations CRUD, et la plupart des applications peuvent être décrites comme des applications pilotées par les données. Les API que j'écris prennent essentiellement des données de la base de données et les renvoient au client sous forme de JSON. OdataToEntity est un outil qui génère une API à partir d'une base de données et élimine le besoin d'écrire une API REST distincte.


Dans cet article, je montrerai comment OdataToEntity peut aider à éliminer le travail ennuyeux d'écriture des méthodes CRUD. Dans le dernier article, j'ai expliqué comment créer un service OData avec un minimum de codage, dans cet article, je vais montrer comment procéder sans écrire de code.


Cette fonctionnalité est disponible dans le projet OdataToEntity.EfCore.DynamicDataContext , qui fait partie de la bibliothèque OdataToEntity. Un exemple de serveur HTTP est implémenté sous la forme d'un programme de console qui accepte une chaîne de connexion à la base de données en entrée. Bases de données prises en charge: MySql, PostgreSql, Sql Server. En plus des tables et des opérations CRUD sur celles-ci, des vues, des procédures stockées et des fonctions sont disponibles.


Description du serveur HTTP


Le code source du serveur est disponible sur GitHub .
La configuration du serveur s'effectue via le fichier de configuration . Il s'agit d'un fichier core Asp .net standard dans lequel la clé OdataToEntity est ajoutée


"OdataToEntity": { "BasePath" : "api", "Provider": "sqlserver", "ConnectionString": "Server=.\\sqlexpress;Initial Catalog=OdataToEntity;Trusted_Connection=Yes;", "UseRelationalNulls": true, "InformationSchemaMappingFileName": "InformationSchemaMapping.json" } 

"BasePath" est le chemin de base dans l'URL du serveur.
"Provider" - type de base de données, les valeurs possibles sont mysql, postgresql, sqlserver.
"ConnectionString" est la chaîne de connexion à la base de données.
"UseRelationalNulls" - indique s'il faut utiliser la sémantique de la base de données relationnelle
lors de la comparaison des valeurs nulles.
"InformationSchemaMappingFileName" - paramètre supplémentaire pour afficher la base de données dans l'API.


Le programme détecte automatiquement les procédures, fonctions, relations entre les tables de base de données, vérifiant leurs clés étrangères. J'utilise ceci pour incorporer des relations dans un schéma de service OData. Pour personnaliser davantage les noms, utilisez le fichier InformationSchemaMapping.json , qui est la classe sérialisée InformationSchemaMapping .
La touche "Opérations" décrit les procédures et fonctions stockées et "Tables" décrit les tables et les vues. Propriétés "DbName" - le nom dans la base de données, "EdmName" - le nom dans le service, "Exclude" exclut la base de données et l'objet de service. Si la procédure / fonction stockée renvoie une table, le nom de la table doit être défini dans la propriété "ResultTableDbName". Pour modifier le nom de la propriété de navigation, utilisez la clé "Navigations", où la propriété "TargetTableName" pointe vers la table cible de la propriété de navigation et "NavigationName" - son nom. Si la table contient plusieurs clés étrangères pour la même table, pour distinguer ces propriétés de navigation, au lieu de "TargetTableName", vous devez spécifier "ConstraintName" - le nom de la clé étrangère de la base de données. Pour la propriété plusieurs-à-plusieurs, vous devez spécifier "ManyToManyTarget" - le nom de la table cible (pour plus d'informations sur l'implémentation plusieurs-à-plusieurs, voir ce lien ).


Exemple de code


Si vous devez utiliser cette fonctionnalité dans votre code, ajoutez un lien vers le projet OdataToEntity.EfCore.DynamicDataContext


 //Load our schema mappings (optional) InformationSchemaMapping informationSchemaMapping = GetMappings(); //Configure context var optionsBuilder = new DbContextOptionsBuilder<DynamicDbContext>(); optionsBuilder = optionsBuilder.UseSqlServer("Server=.\\sqlexpress;Initial Catalog=OdataToEntity;Trusted_Connection=Yes;"); IEdmModel dynamicEdmModel; //create database schema using (ProviderSpecificSchema providerSchema = new SqlServerSchema(optionsBuilder.Options)) using (var metadataProvider = providerSchema.CreateMetadataProvider(informationSchemaMapping)) { //create ef entity types manager DynamicTypeDefinitionManager typeDefinitionManager = DynamicTypeDefinitionManager.Create(metadataProvider); //Create adapter data access var dataAdapter = new DynamicDataAdapter(typeDefinitionManager); //Build OData edm model dynamicEdmModel = dataAdapter.BuildEdmModel(metadataProvider); } //Create query parser var parser = new OeParser(new Uri("http://dummy"), dynamicEdmModel); //Query var uri = new Uri("http://dummy/Orders?$expand=Customer,Items&$orderby=Id"); //The result of the query var stream = new MemoryStream(); //Execute query await parser.ExecuteGetAsync(uri, OeRequestHeaders.JsonDefault, stream, CancellationToken.None); stream.Position = 0; //Get result as string Console.WriteLine(new StreamReader(stream).ReadToEnd()); 

Comment ça marche


Les vues information_schema génèrent le contexte Entity Framework. Les entités du contexte sont des descendants de la classe abstraite DynamicType . Cette classe impose des restrictions sur le nombre total de colonnes dans la table, il ne doit pas y en avoir plus de 50. Le nombre de propriétés de navigation ne doit pas dépasser pour les propriétés de la clé primaire 50, de la clé étrangère 30.


Le nombre total de tables et de vues est limité à 110, ce nombre est limité par les implémentations de classe DynamicType . Vous pouvez augmenter le nombre de propriétés ou de classes en les ajoutant au code source.
Le schéma OData est construit sur la base du contexte Entity Framework, comme déjà décrit dans mon article précédent. Ce schéma est nécessaire pour traduire la demande dans l'arborescence d'expression, qui est transmise au contexte EntityFramework.


Structure du code source


Résolu - sln \ OdataToEntity.Test.DynamicDataContext.sln
Projet - source \ OdataToEntity.EfCore.DynamicDataContext
Serveur HTTP - test \ OdataToEntity.Test.DynamicDataContext.AspServer
Tests - OdataToEntity.Test.DynamicDataContext
Scripts de base de test SQL - test \ sql_scripts

Source: https://habr.com/ru/post/fr459656/


All Articles