shashisadasivan / EDMXTrimmer

D365 Finance and operations EDMX trimmer
MIT License
22 stars 12 forks source link

Omits EntityType #20

Closed fartwhif closed 1 year ago

fartwhif commented 1 year ago

Thanks for the effort, however we are interested in more than what it captures

EntitySets are extracted, but not EntityTypes. Only interested in EntityTypes

EXEC:

C:\Users\user\Desktop\EDMXTrimmer\EDMXTrimmer\EDMXTrimmer\bin\Debug\netcoreapp3.1>dotnet edmxtrimmer.dll --edmxfile "C:\Users\user\Downloads\metadata.xml" --outputfilename "C:\Users\user\Desktop\metadata_pruned.xml" --entitiestokeep "(Position)" --entitiesareregularexpressions --verbose
EDMX Saved to file: C:\Users\user\Desktop\metadata_pruned.xml
EDMX Saved to file: C:\Users\user\Desktop\metadata_pruned.xml

IN:

Search "position" (17 hits in 1 file of 1 searched)
  C:\Users\user\Downloads\metadata.xml (17 hits)
    Line 447:               <NavigationProperty Name="ABCPosition"
    Line 448:                                       Type="Collection(NAV.ABCPosition)"
    Line 13236:                 <Property Name="Position_Code"
    Line 13240:                                 String="Position Code" />
    Line 13245:                 <Property Name="Position_Department"
    Line 13249:                                 String="Position Department" />
    Line 13254:                 <Property Name="Position_Category"
    Line 13258:                                 String="Position Category" />
    Line 14234:                 <Property Name="Position_Num"
    Line 14238:                                 String="Position Num" />
    Line 14437:             <EntityType Name="ABCPosition">
    Line 14439:                     <PropertyRef Name="Position_Num" />
    Line 14441:                 <Property Name="Position_Num"
    Line 14446:                                 String="Position Num" />
    Line 14656:                             String="ABCPosition" />
    Line 45074:                 <EntitySet Name="ABCPosition"
    Line 45075:                             EntityType="NAV.ABCPosition">

OUT:

Search "position" (2 hits in 1 file of 1 searched)
  C:\Users\user\Desktop\metadata_pruned.xml (2 hits)
    Line 160:         <EntitySet Name="ABCPosition" EntityType="NAV.ABCPosition">
    Line 160:         <EntitySet Name="ABCPosition" EntityType="NAV.ABCPosition">
FH-Inway commented 1 year ago

Hi, thanks for your request. EDMXTrimmer should actually retain the EntityTypes in the trimmed EDMX file as well. Could you provide a complete EDMX file where the EntityTypes get trimmed so we can reproduce the issue?

fartwhif commented 1 year ago

i would but i don't know how much of it is sensitive and don't have the time to curate it for this exercise

FH-Inway commented 1 year ago

Understood, maybe you can find some time in the future. Without a file to reproduce the issue, I'm not sure what we can do to otherwise analyze this issue. You can also contact me directly and send me a file if you feel more comfortable doing that instead of sharing it here.

fartwhif commented 1 year ago

This fixes it for Business Central 22

diff --git "a/EDMXTrimmer/EDMXTrimmer/EdmxTrimmer.cs" "b/EDMXTrimmer/EDMXTrimmer/EdmxTrimmer.cs"
index 278507e..4178175 100644
--- "a/EDMXTrimmer/EDMXTrimmer/EdmxTrimmer.cs"
+++ "b/EDMXTrimmer/EDMXTrimmer/EdmxTrimmer.cs"
@@ -19,11 +19,13 @@ namespace EDMXTrimmer
         private const string ENTITY_TYPE = "EntityType";
         private const string ENTITY_SET = "EntitySet";
         private const string NAVIGATION_PROPERTY = "NavigationProperty";
+        private const string ANNOTATION = "Annotations";
         private const string ACTION = "Action";
+        private const string ACTIONIMPORT = "ActionImport";
         private const string ATTRIBUTE_NAME = "Name";
         private const string ATTRIBUTE_TYPE = "Type";
         private const string ATTRIBUTE_RETURN_TYPE = "ReturnType";
-        private const string ENTITYNAMESPACE = "Microsoft.Dynamics.DataEntities.";
+        private const string ENTITYNAMESPACE = "NAV.";

         public EdmxTrimmer(
             string edmxFile, 
@@ -174,6 +176,18 @@ namespace EDMXTrimmer
                     Any(childNode => EntityExists(childNode, entityType)))).ToList()
                 .ForEach(n => n.ParentNode.RemoveChild(n));

+            // Remove all Action Imports         
+            this._xmlDocument.GetElementsByTagName(ACTIONIMPORT).Cast<XmlNode>()
+                .Where(acti => !entityTypesFound.Any(entityType => acti.ChildNodes.Cast<XmlNode>().
+                    Any(childNode => EntityExists(childNode, entityType)))).ToList()
+                .ForEach(n => n.ParentNode.RemoveChild(n));
+
+            // Remove all Primary Annotations
+            this._xmlDocument.GetElementsByTagName(ANNOTATION).Cast<XmlNode>()
+                .Where(anno => !entityTypesFound.Any(entityType => anno.ChildNodes.Cast<XmlNode>().
+                    Any(childNode => EntityExists(childNode, entityType)))).ToList()
+                .ForEach(n => n.ParentNode.RemoveChild(n));
+
             // Determine enums to keep
             List<String> enumTypesFound = new List<string>();
             // Enums from entity type properties
FH-Inway commented 1 year ago

Nice, thanks for the diff!

The main issue seems to be the ENTITYNAMESPACE. The change from the diff would support Business Central, but break the tool for Finance and Operations folks. Instead, I propose that the namespace is determined from the input .edmx file from the Schema tag.

I also looked into the removal of action imports and primary annotations. I don't think those exist in the Finance and Operations .edmx and I'm not sure about their purpose.

For primary annotations, I found https://github.com/waldo1001/BusinessCentralOpenAPIToolkit/blob/main/MicrosoftAPIv2.0/MicrosoftAPIv2.0.edmx, which seems to be an older version of the Business Central .edmx. It contains Annotations tags as children of the Schema tag. Those seem to be setting IsLanguageDependent and IsBidirectionalPartnerNavigation flags for entities. The diff would remove them all, even if the entities and their navigation property referenced by the annotations' target attribute are kept in the trimmed file. I'm not sure about the relevance of those annotations. Since the logic to only remove the ones not required could get a bit tricky, I would propose an optional parameter that lets the user control if the annotations are removed or not. Default would be false.

Regarding action imports, those seem to be actions not bound to an entity. I'm not sure just removing them is the best solution here, as some people might be interested in them. I would again propose an optional argument that lets the user control if those actions are removed or not. Default would be false.

I will work on a change request for the namespace. Let me know if the proposals for annotations and import actions would work for you.

FH-Inway commented 1 year ago

@fartwhif Thanks for the test. Do you have remarks on my proposals for primary annotations and action imports? Otherwise I would go ahead and implement them.

fartwhif commented 1 year ago

Sounds good, those switches are what I would have asked for. Thanks again for the tool and the improvements.

FH-Inway commented 1 year ago

@fartwhif Thanks for the feedback on #22 , I will close this issue. Feel free to add further comments, reopen it or create a new issue. You can get the latest version 0.1.1 that includes that functionality now also here: https://github.com/shashisadasivan/EDMXTrimmer/releases/tag/0.1.1.20230624