how to map back to get the actual sql table column name apart from model in MVC?

前端 未结 2 892
面向向阳花
面向向阳花 2020-12-12 06:18

I am mapping my table column name to generic way in to use them in model. like:

        public UserEntityMapper()
        {
            ToTable(\"tbl_User\")         


        
2条回答
  •  死守一世寂寞
    2020-12-12 06:45

    Reading the mappings

    I've seen similar questions before and several less than satisfying solutions based on splitting the SQL string generated by a DbSet. Attempts to access the mapping metadata are blocked by unaccessible internal types. It kept (and keeps) bugging me that this information is so hidden. Atter all, it's your own mapping.

    So I did some fooling around to see if something can be improved here. Since everything can easily be read from an edmx file, that's where I started. And finally got there. It the following code, the edmx file is in an XDocument called doc. I'll explain the code below.

    var xn = XName.Get("Mappings", doc.Root.GetDefaultNamespace().ToString());
    var mappingsNode = doc.Descendants(xn).Descendants().First();
    var mappingDoc = XDocument.Parse(mappingsNode.ToString());
    xn = XName.Get("MappingFragment", mappingDoc.Root
                                                .GetDefaultNamespace().ToString());
    var mappings = mappingDoc
                .Descendants(xn)
                .Select(x => new
                    {
                        Entity = x.Attribute("StoreEntitySet").Value,
                        Mapping = x.Descendants()
                                    .Select(d => new 
                                                { 
                                                  Property = d.Attribute("Name")
                                                              .Value,
                                                  Column = d.Attribute("ColumnName")
                                                            .Value
                                                })
                    });
    

    Sample output from a very small edmx:

    Entity      Property        Column
    ---------------------------------------------
    Category    CategoryID      CategoryID 
                Name            CategoryName 
                Description     Description 
    
    Product     ProductID       ProductID 
                Name            ProductName 
                QuantityPerUnit QuantityPerUnit 
                UnitPrice       UnitPrice 
                StartDate       StartDate 
    

    Explanation:

    An edmx file has a fixed structure that I summarize here:

    
      
        
        ...
        
        
          
            
              
                
                  
                    
                    ...
                  
                
              
              
              
            
          
        
        
        ...
        
      
      
      ...
      
    
    

    The Mappings part is what we're after. So I first create a new XDocument of this part:

    var xn = XName.Get("Mappings", doc.Root.GetDefaultNamespace().ToString());
    // First descendant of the "Mappings" node, which is the "Mapping" node
    var mappingsNode = doc.Descendants(xn).Descendants().First();
    var mappingDoc = XDocument.Parse(mappingsNode.ToString());
    

    The "Mapping" node has its own namespace, so I parse it into an XDocument in order to get this namespace by which I can query its nodes. Thus, I can get to the mapping fragments:

    xn = XName.Get("MappingFragment", mappingDoc.Root
                                                .GetDefaultNamespace().ToString());
    var mappings = mappingDoc.Descendants(xn) ...
    

    Maybe there is a better way to get to these nodes, but I'm not very fluent in this XDocument API.

    Then it's a question of pulling out the right attributes and project them to a queryable structure.

    Thoughts

    It works, OK, but it's not elegant at all. It greatly depends on the edmx structure, so it can break any moment. I think there should come a decent, convenient way to read a context's metadata.

    By the way, if you work code-first you can generate an edmx by an EdmxWriter.

提交回复
热议问题