I've been creating a nice T4 template for a repository pattern for my entities. Instead of manually parsing the xml in the edmx file I use the EdmItemCollection to create a object graph presentation for the conceptual model.
我一直在为我的实体创建一个很好的T4模板来存储模式。我没有手动解析edmx文件中的xml,而是使用EdmItemCollection为概念模型创建对象图表。
I've been able to get a lot of information out of this model. But I cant find where to locate the Getter and Setter access modifiers. They are present in the CSDL part of the edmx file.
我已经能够从这个模型中获得大量信息。但是我找不到Getter和Setter访问修饰符的位置。它们存在于edmx文件的CSDL部分中。
Example:
<Property Name="CustomerID" Type="String" Nullable="false" MaxLength="5" Unicode="true" FixedLength="true"
a:SetterAccess="Public" xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" />
Where in the object graph should I look for this information?
我应该在对象图中的哪个位置查找此信息?
Here is an example of how I parse the object tree.
这是我如何解析对象树的一个例子。
EdmItemCollection edmItems = new EdmItemCollection(new XmlReader[] { csdlReader });
var ownEntities = from item in edmItems
where item.BuiltInTypeKind == BuiltInTypeKind.EntityType
select item as EntityTypeBase;
Entities = (from ent in ownEntities // Entities is a property, therefore no declaration
select new Entity
{
Name = ent.Name,
SetName = (from entSet in entityContainer.BaseEntitySets
where (entSet.ElementType == ent) || (ent.BaseType != null && (entSet.ElementType.FullName.Equals(ent.BaseType.FullName)))
select entSet.Name).FirstOrDefault(),
Keys = (from keys in ent.KeyMembers
select new Entity.Member
{
Name = keys.Name,
Type = keys.TypeUsage.EdmType.Name
}).ToList(),
Properties = (from prop in ent.Members
select new Entity.Member
{
Name = prop.Name,
Type = prop.TypeUsage.EdmType.Name,
IsCollection = prop.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType
}).ToList()
}).ToList();
I hope it's clear in which direction I'm going.
我希望我明白我要去哪个方向。
After a lot of reflectoring trough the code of the EdmItemCollection that it doesn't load the http://schemas.microsoft.com/ado/2006/04/codegeneration schema, so it just ignores those properties.
经过大量的反射,通过EdmItemCollection的代码,它没有加载http://schemas.microsoft.com/ado/2006/04/codegeneration架构,所以它只是忽略这些属性。
But I'm hoping somebody can help me find out how to locate this information?
但我希望有人可以帮我找到如何找到这些信息?
1 个解决方案
#1
1
Thanks to Noam Ben-Ami from Microsoft who pointed me to the blog post Annotations in CSDL I'm able to answered my own question.
感谢微软的Noam Ben-Ami向我指出CSDL中的博客文章Annotations,我能够回答我自己的问题。
Everything which is not directly presented in the Object Model from the Edm types can still be found in the MetadataProperties (which contains every xml property of the element, even the ones which are represented as typed properties).
在Edm类型的对象模型中没有直接呈现的所有内容仍然可以在MetadataProperties中找到(它包含元素的每个xml属性,甚至是表示为类型属性的属性)。
I just have to look for a MetadataProperty which name begins with "http://schemas.microsoft.com/ado/2006/04/codegeneration:" and I've found it.
我只需要查找一个名为“http://schemas.microsoft.com/ado/2006/04/codegeneration:”的MetadataProperty,我就找到了它。
To answer my code example:
要回答我的代码示例:
String codeGenerationXmlns = "http://schemas.microsoft.com/ado/2006/04/codegeneration";
EdmItemCollection edmItems = new EdmItemCollection(new XmlReader[] { csdlReader });
var ownEntities = from item in edmItems
where item.BuiltInTypeKind == BuiltInTypeKind.EntityType
select item as EntityTypeBase;
var entityContainer = (from item in edmItems
where item.BuiltInTypeKind == BuiltInTypeKind.EntityContainer
select item as EntityContainer).FirstOrDefault();
Entities = (from ent in ownEntities
select new Entity
{
Name = ent.Name,
SetName = (from entSet in entityContainer.BaseEntitySets
where (entSet.ElementType == ent) || (ent.BaseType != null && (entSet.ElementType.FullName.Equals(ent.BaseType.FullName)))
select entSet.Name).FirstOrDefault(),
IsPublic = ((from metaProps in ent.MetadataProperties
where metaProps.Name.Equals(codeGenerationXmlns + ":TypeAccess")
select metaProps.Value).FirstOrDefault() ?? "Public").Equals("Public"),
Keys = (from keys in ent.KeyMembers
select new Entity.Member
{
Name = keys.Name,
Type = keys.TypeUsage.EdmType.Name
}).ToList(),
Properties = (from prop in ent.Members
select new Entity.Member
{
Name = prop.Name,
Type = prop.TypeUsage.EdmType.Name,
IsCollection = prop.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType,
PrivateGetter = ((from metaProps in prop.MetadataProperties
where metaProps.Name.Equals(codeGenerationXmlns + ":GetterAccess")
select metaProps.Value).FirstOrDefault() ?? "Public").Equals("Private"),
PrivateSetter = ((from metaProps in prop.MetadataProperties
where metaProps.Name.Equals(codeGenerationXmlns + ":SetterAccess")
select metaProps.Value).FirstOrDefault() ?? "Public").Equals("Private"),
}).ToList()
}).ToList();
#1
1
Thanks to Noam Ben-Ami from Microsoft who pointed me to the blog post Annotations in CSDL I'm able to answered my own question.
感谢微软的Noam Ben-Ami向我指出CSDL中的博客文章Annotations,我能够回答我自己的问题。
Everything which is not directly presented in the Object Model from the Edm types can still be found in the MetadataProperties (which contains every xml property of the element, even the ones which are represented as typed properties).
在Edm类型的对象模型中没有直接呈现的所有内容仍然可以在MetadataProperties中找到(它包含元素的每个xml属性,甚至是表示为类型属性的属性)。
I just have to look for a MetadataProperty which name begins with "http://schemas.microsoft.com/ado/2006/04/codegeneration:" and I've found it.
我只需要查找一个名为“http://schemas.microsoft.com/ado/2006/04/codegeneration:”的MetadataProperty,我就找到了它。
To answer my code example:
要回答我的代码示例:
String codeGenerationXmlns = "http://schemas.microsoft.com/ado/2006/04/codegeneration";
EdmItemCollection edmItems = new EdmItemCollection(new XmlReader[] { csdlReader });
var ownEntities = from item in edmItems
where item.BuiltInTypeKind == BuiltInTypeKind.EntityType
select item as EntityTypeBase;
var entityContainer = (from item in edmItems
where item.BuiltInTypeKind == BuiltInTypeKind.EntityContainer
select item as EntityContainer).FirstOrDefault();
Entities = (from ent in ownEntities
select new Entity
{
Name = ent.Name,
SetName = (from entSet in entityContainer.BaseEntitySets
where (entSet.ElementType == ent) || (ent.BaseType != null && (entSet.ElementType.FullName.Equals(ent.BaseType.FullName)))
select entSet.Name).FirstOrDefault(),
IsPublic = ((from metaProps in ent.MetadataProperties
where metaProps.Name.Equals(codeGenerationXmlns + ":TypeAccess")
select metaProps.Value).FirstOrDefault() ?? "Public").Equals("Public"),
Keys = (from keys in ent.KeyMembers
select new Entity.Member
{
Name = keys.Name,
Type = keys.TypeUsage.EdmType.Name
}).ToList(),
Properties = (from prop in ent.Members
select new Entity.Member
{
Name = prop.Name,
Type = prop.TypeUsage.EdmType.Name,
IsCollection = prop.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType,
PrivateGetter = ((from metaProps in prop.MetadataProperties
where metaProps.Name.Equals(codeGenerationXmlns + ":GetterAccess")
select metaProps.Value).FirstOrDefault() ?? "Public").Equals("Private"),
PrivateSetter = ((from metaProps in prop.MetadataProperties
where metaProps.Name.Equals(codeGenerationXmlns + ":SetterAccess")
select metaProps.Value).FirstOrDefault() ?? "Public").Equals("Private"),
}).ToList()
}).ToList();