问题
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