Using IEdmModel to resolve EntitySet name into EntityName (Products -> Product)

血红的双手。 提交于 2019-12-12 02:33:59

问题


I am using a OData Service on top of Entity Framework

var uri = new Uri("http://localhost:9876/Service.svc");
var context = new DataServiceContext(uri, , DataServiceProtocolVersion.V3);
var model = EdmxReader.Parse(
    XmlReader.Create(context.GetMetadataUri().AbsoluteUri)
);
context.Format.UseJson(model);

Now I need to figure out the entity name name from an EntitySet name

My entities are called Product or Customer but the Name of the EntitySet can be either Products or CustomerSet or something else.

Since I already loaded the IEdmModel and the information is located in the $metadata is there a way to resolve the entity name from the IEdmModel?


回答1:


Since I haven't found a way to extract the information I want I ended up creating my own solution.

First I read the metadata xml into a string to only have a roundtrip to the service. Then I create my IEdmModel from the string and create my own class which extracts all information from the metadata xml.

    var client = new WebClient();
    var metadata = client.DownloadString(metadataUri);
    var model = CreateModel(metadata);
    var schema = CreateSchema(metadata);

    private static IEdmModel CreateModel(string metadata)
    {
        using (var reader = new StringReader(metadata))
        using (var xmlReader = XmlReader.Create(reader))
        {
            return EdmxReader.Parse(xmlReader);
        }
    }

    private static Schema.Schema CreateSchema(string metadata)
    {
        using (var reader = new StringReader(metadata))
        using (var xmlReader = XmlReader.Create(reader))
        {
            var root = XElement.Load(xmlReader);
            return SchemaBuilder.GetSchema(root);
        }
    }

Here is the code to read the Schema from the metadata, hopefully someone will find this useful. I did not include the classes I use but they are just POCOS with no code.

    public static Schema GetSchema(XElement root)
    {

        XNamespace edmx = root.GetNamespaceOfPrefix("edmx");
        XNamespace edm = root.Element(edmx + "DataServices").Elements().First().GetDefaultNamespace();

        var result = from s in root.Element(edmx + "DataServices").Elements(edm + "Schema")
                     select new
                     {
                         Namespace = (string)s.Attribute("Namespace"),
                         EntityTypes = from e in s.Elements(edm + "EntityType")
                                       select new EntityType
                                       {
                                           Name = (string)e.Attribute("Name"),
                                           Key = from k in e.Element(edm + "Key").Elements(edm + "PropertyRef")
                                                 select (string)k.Attribute("Name"),
                                           Properties = from p in e.Elements(edm + "Property")
                                                        select new Property
                                                        {
                                                            Name = (string)p.Attribute("Name"),
                                                            Type = (string)p.Attribute("Type"),
                                                            Nullable = (bool)p.Attribute("Nullable", true),
                                                            MaxLength = (string)p.Attribute("MaxLength"),
                                                            FixedLength = (bool)p.Attribute("FixedLength", false),
                                                        },
                                           NavigationProperties = from p in e.Elements(edm + "NavigationProperty")
                                                                  select new NavigationProperty
                                                                  {
                                                                      Name = (string)p.Attribute("Name"),
                                                                      Relationship = (string)p.Attribute("Relationship"),
                                                                      ToRole = (string)p.Attribute("ToRole"),
                                                                      FromRole = (string)p.Attribute("FromRole"),
                                                                  }
                                       },
                         Associations = from a in s.Elements(edm + "Association")
                                        select new Association
                                        {
                                            Name = (string)a.Attribute("Name"),
                                            Ends = from et in a.Elements(edm + "End")
                                                   select new AssociationEnd
                                                   {
                                                       Type = (string)et.Attribute("Type"),
                                                       Role = (string)et.Attribute("Role"),
                                                       Multiplicity = (string)et.Attribute("Multiplicity"),
                                                   }
                                        },
                         AssociationSets = from @as in s.Elements(edm + "EntityContainer").Elements(edm + "AssociationSet")
                                           select new AssociationSet
                                           {
                                               Name = (string)@as.Attribute("Name"),
                                               Association = (string)@as.Attribute("Association"),
                                               Ends = from r in @as.Elements(edm + "End")
                                                      select new AssociationSetEnd
                                                      {
                                                          Role = (string)r.Attribute("Role"),
                                                          EntitySet = (string)r.Attribute("EntitySet"),
                                                      },
                                           },
                        EntitySets = from @es in s.Elements(edm + "EntityContainer").Elements(edm + "EntitySet")
                                     select new EntitySet
                                            {
                                                Name = (string)@es.Attribute("Name"),
                                                EntityType = (string)@es.Attribute("EntityType"),
                                            },

                     };

        return new Schema
        {
            Namespace = result.First().Namespace,
            EntityTypes = result.SelectMany(x => x.EntityTypes).ToDictionary(x => x.Name),
            Associations = result.SelectMany(x => x.Associations).ToDictionary(x => x.Name),
            AssociationSets = result.SelectMany(x => x.AssociationSets).ToDictionary(x => x.Name),
            EntitySets = result.SelectMany(x => x.EntitySets).ToDictionary(x => x.Name),
        };
    }


来源:https://stackoverflow.com/questions/29768118/using-iedmmodel-to-resolve-entityset-name-into-entityname-products-product

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!