使用 IEdmModel 将 EntitySet 名称解析为 EntityName(产品 -> 产品)
Using IEdmModel to resolve EntitySet name into EntityName (Products -> Product)
我在 Entity Framework
之上使用 OData 服务
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 名称中找出实体名称
我的实体名为 Product
或 Customer
,但 EntitySet
的名称可以是 Products
或 CustomerSet
或其他名称。
因为我已经加载了 IEdmModel
并且信息位于 $metadata
中,有没有办法从 IEdmModel 解析实体名称?
由于我还没有找到提取所需信息的方法,所以我最终创建了自己的解决方案。
首先,我将元数据 xml 读取到一个字符串中,以便仅往返于该服务。
然后我从字符串创建我的 IEdmModel
并创建我自己的 class,它从元数据 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);
}
}
这是从元数据中读取架构的代码,希望有人会发现它有用。我没有包括我使用的 classes,但它们只是没有代码的 POCOS。
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),
};
}
我在 Entity Framework
之上使用 OData 服务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 名称中找出实体名称
我的实体名为 Product
或 Customer
,但 EntitySet
的名称可以是 Products
或 CustomerSet
或其他名称。
因为我已经加载了 IEdmModel
并且信息位于 $metadata
中,有没有办法从 IEdmModel 解析实体名称?
由于我还没有找到提取所需信息的方法,所以我最终创建了自己的解决方案。
首先,我将元数据 xml 读取到一个字符串中,以便仅往返于该服务。
然后我从字符串创建我的 IEdmModel
并创建我自己的 class,它从元数据 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);
}
}
这是从元数据中读取架构的代码,希望有人会发现它有用。我没有包括我使用的 classes,但它们只是没有代码的 POCOS。
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),
};
}