First, here is the class I'm populating in the main method. Of course, you could add properties to this as necessary:
Update: There is a bug in the code below. It's impossible to edit the (pasted in) HTML now. the select after "var foreignKeyNames" below should be:
select ( p.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One ) ?
( (AssociationType)p.RelationshipType ).ReferentialConstraints[0].FromProperties[0].Name :
( (AssociationType)p.RelationshipType ).ReferentialConstraints[0].ToProperties[0].Name );
public
class
EntityTypeInfo
{
public string EntityName { get; set; }
public string PropertyName { get; set; }
public Type EntityType { get; set; }
///
/// Identity, Computed columns
///
public bool StoreGenerated { get; set; }
public bool IsForeignKey { get; set; }
}
{
public string EntityName { get; set; }
public string PropertyName { get; set; }
public Type EntityType { get; set; }
///
/// Identity, Computed columns
///
public bool StoreGenerated { get; set; }
public bool IsForeignKey { get; set; }
}
Now the main method along with a helper method (see update above):
- /// <summary>
- /// For the given table/entity list, build a list of type info.
- /// </summary>
- public static List<EntityTypeInfo> SimplePropertiesFrom( ObjectContext context, List<string> tables )
- {
- var result = new List<EntityTypeInfo>();
- /// We have to draw from two different spaces to get all the info we need.
- var conceptualMetadata = context.MetadataWorkspace.GetItems( DataSpace.CSpace );
- /// context.MetadataWorkspace.GetItems() for storage space only works if queries have already run which we can't ensure here.
- var storageMetadata = ( (EntityConnection)context.Connection ).GetMetadataWorkspace().GetItems( DataSpace.SSpace );
- var query = from c in conceptualMetadata
- join s in storageMetadata on
- c.BuiltInTypeKind == BuiltInTypeKind.EntityType ? ( (EntityType)c ).Name : "X" // If the item isn't an EntityType, we don't want a join, so just make these 2 values different
- equals
- s.BuiltInTypeKind == BuiltInTypeKind.EntityType ? ( (EntityType)s ).Name : ""
- where c.BuiltInTypeKind == BuiltInTypeKind.EntityType
- select new { conceptual = c as EntityType, storage = s as EntityType };
- query.ToList().ForEach( field =>
- {
- if ( tables.Contains( field.conceptual.Name ) )
- {
- var foreignKeyProps = ( from p in field.conceptual.NavigationProperties
- where p.RelationshipType is AssociationType && ((AssociationType)p.RelationshipType).IsForeignKey
- select ( ( AssociationType )p.RelationshipType ).ReferentialConstraints[0].FromProperties[0].Name );
- foreach ( var p in field.conceptual.Properties )
- {
- result.Add( new EntityTypeInfo
- {
- EntityName = field.conceptual.Name,
- PropertyName = p.Name,
- EntityType = ( (PrimitiveType)p.TypeUsage.EdmType ).ClrEquivalentType,
- StoreGenerated = IsStoreGenerated( p, field.storage ),
- IsForeignKey = foreignKeyProps.Contains( p.Name )
- } );
- }
- }
- } );
- return result;
- }
- private static bool IsStoreGenerated( EdmProperty conceptualEntityProperty, EntityType storageEntityType )
- {
- EdmMember storageProperty;
- storageEntityType.Members.TryGetValue( conceptualEntityProperty.Name, true, out storageProperty );
- if ( storageProperty == null )
- {
- return false;
- }
- else
- {
- Facet f;
- if ( storageProperty.TypeUsage.Facets.TryGetValue( "StoreGeneratedPattern", false, out f) )
- {
- return ( ( (StoreGeneratedPattern)f.Value ) == StoreGeneratedPattern.Identity ) || ( ( (StoreGeneratedPattern)f.Value ) == StoreGeneratedPattern.Computed );
- }
- else
- {
- /// If it's not store generated, the above property won't be there (StoreGeneratedPattern.None is never referenced).
- return false;
- }
- }
- }
No comments:
Post a Comment