使用 IEdmModel 将 EntitySet 名称解析为 EntityName (Products -> Product) [英] Using IEdmModel to resolve EntitySet name into 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
我的实体被称为 Product
或 Customer
但EntitySet
的名称可以是 Products
或 CustomerSet
或其他.
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屋!