使用 IEdmModel 将 EntitySet 名称解析为 EntityName (Products -> Product) [英] Using IEdmModel to resolve EntitySet name into EntityName (Products -> Product)

查看:70
本文介绍了使用 IEdmModel 将 EntitySet 名称解析为 EntityName (Products -> Product)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在实体框架之上使用 OData 服务

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);

现在我需要从 EntitySet 名称中找出实体名称

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

我的实体被称为 ProductCustomerEntitySet 的名称可以是 ProductsCustomerSet 或其他.

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

既然我已经加载了 IEdmModel 并且信息位于 $metadata 中,有没有办法从 IEdmModel 解析实体名称?

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?

推荐答案

由于我还没有找到提取所需信息的方法,因此我最终创建了自己的解决方案.

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

首先,我将元数据 xml 读取到一个字符串中,以便仅往返服务.然后我从字符串创建我的 IEdmModel 并创建我自己的类,它从元数据 xml 中提取所有信息.

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);
        }
    }

这是从元数据中读取架构的代码,希望有人会发现这很有用.我没有包括我使用的类,但它们只是没有代码的 POCOS.

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),
        };
    }

这篇关于使用 IEdmModel 将 EntitySet 名称解析为 EntityName (Products -> Product)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆