خدمة OData دون كتابة التعليمات البرمجية


واحدة من أهم جوانب تطوير البرمجيات هي النماذج الأولية السريعة. تتطلب معظم الخدمات بعض عمليات CRUD على الأقل ، ويمكن وصف معظم التطبيقات كتطبيقات تعتمد على البيانات. واجهات برمجة التطبيقات التي أكتبها تأخذ البيانات بشكل أساسي من قاعدة البيانات وإعادتها إلى العميل باسم JSON. OdataToEntity هي أداة تنشئ واجهة برمجة تطبيقات من قاعدة بيانات وتلغي الحاجة إلى كتابة واجهة برمجة تطبيقات REST منفصلة.


في هذه المقالة ، سأوضح كيف يمكن لـ OdataToEntity المساعدة في القضاء على الوظيفة الممل المتمثلة في كتابة أساليب CRUD. في المقالة الأخيرة ، تحدثت عن كيفية إنشاء خدمة OData مع الحد الأدنى من الترميز ، في هذه المقالة سوف تظهر كيفية القيام بذلك دون كتابة التعليمات البرمجية على الإطلاق.


تتوفر هذه الوظيفة في مشروع OdataToEntity.EfCore.DynamicDataContext ، الذي يعد جزءًا من مكتبة OdataToEntity. يتم تطبيق مثال لخادم HTTP في شكل برنامج وحدة تحكم يقبل سلسلة اتصال بقاعدة البيانات كمدخل. قواعد البيانات المدعومة: MySql ، PostgreSql ، Sql Server. بالإضافة إلى الجداول وعمليات CRUD عليها ، تتوفر طرق العرض والإجراءات المخزنة والوظائف.


وصف خادم HTTP


كود مصدر الخادم متاح على جيثب .
يتم تكوين الخادم من خلال ملف التكوين . هذا هو ملف Asp .net أساسي قياسي حيث يتم إضافة مفتاح OdataToEntity


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

"BasePath" هو المسار الأساسي في عنوان URL الخاص بالخادم.
"موفر" - نوع قاعدة البيانات ، والقيم المحتملة هي mysql ، postgresql ، sqlserver.
"ConnectionString" هي سلسلة الاتصال بقاعدة البيانات.
يشير "UseRelationalNulls" - إلى ما إذا كان يجب استخدام دلالات قاعدة البيانات العلائقية
عند مقارنة القيم صفر.
"InformationSchemaMappingFileName" - إعداد إضافي لعرض قاعدة البيانات في API.


البرنامج تلقائيا بالكشف عن الإجراءات والوظائف والعلاقات بين جداول قاعدة البيانات ، والتحقق من المفاتيح الخارجية. أنا استخدم هذا لتضمين العلاقات في مخطط خدمة OData. لتخصيص الأسماء بشكل أكبر ، استخدم ملف InformationSchemaMapping.json ، وهو الفئة التسلسلية InformationSchemaMapping .
يصف مفتاح "العمليات" الإجراءات والوظائف المخزنة ، ويصف "الجداول" الجداول وطرق العرض. خصائص "DbName" - الاسم في قاعدة البيانات ، "EdmName" - الاسم في الخدمة ، "استبعاد" يستبعد كائن قاعدة البيانات والخدمة. إذا قام الإجراء / الوظيفة المخزنة بإرجاع جدول ، فيجب تعيين اسم الجدول في خاصية "ResultTableDbName". لتغيير اسم خاصية التنقل ، استخدم مفتاح "Navigate" ، حيث تشير خاصية "TargetTableName" إلى الجدول المستهدف لخاصية التنقل ، و "NavigationName" - اسمها. إذا كان الجدول يحتوي على عدة مفاتيح خارجية لنفس الجدول ، ثم للتمييز بين خصائص التنقل هذه ، بدلاً من "TargetTableName" ، يجب عليك تحديد "ConstraintName" - اسم المفتاح الخارجي لقاعدة البيانات. بالنسبة للعديد من الخصائص ، يجب عليك تحديد "ManyToManyTarget" - اسم الجدول الهدف (لمزيد من المعلومات حول التنفيذ من كثير إلى كثير ، انظر هذا الرابط ).


مثال رمز


إذا كنت بحاجة إلى استخدام هذه الوظيفة في التعليمات البرمجية الخاصة بك ، أضف رابطًا إلى مشروع 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()); 

كيف يعمل؟


طرق عرض information_schema إنشاء سياق Entity Framework. كيانات السياق هي أحفاد فئة مجردة DynamicType . تفرض هذه الفئة قيودًا على إجمالي عدد الأعمدة في الجدول ، ولا ينبغي أن يكون هناك أكثر من 50. يجب ألا يتجاوز عدد خصائص التنقل للخصائص من المفتاح الأساسي 50 ، من المفتاح الخارجي 30.


يقتصر إجمالي عدد الجداول وطرق العرض على 110 ، وهذا الرقم محدود بواسطة تطبيقات فئة DynamicType . يمكنك زيادة عدد الخصائص أو الفئات عن طريق إضافتها إلى التعليمات البرمجية المصدر.
تم بناء مخطط OData على أساس سياق إطار الكيان ، كما هو موضح بالفعل في مقالتي السابقة. يعد هذا المخطط ضروريًا لترجمة الطلب إلى شجرة التعبير ، والتي يتم تمريرها إلى سياق EntityFramework.


هيكل كود المصدر


تم الحل - sln \ OdataToEntity.Test.DynamicDataContext.sln
مشروع - المصدر \ OdataToEntity.EfCore.DynamicDataContext
خادم HTTP - اختبار \ OdataToEntity.Test.DynamicDataContext.AspServer
الاختبارات - OdataToEntity.Test.DynamicDataContext
البرامج النصية قاعدة اختبار SQL - اختبار \ sql_scripts

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


All Articles