Getting column name (sspace) from ospace property name

In the following example, I see how to get a table name of type OSpace:

https://lowrymedia.com/2014/06/10/ef6-1-mapping-between-types-tables-including-derived-types/

But how do I get the SSpace column name from the OSpace property name (i.e. CLR type property)?

Looking through the MetadataProperties properties from the corresponding CSpace property, I see that there is a “Configuration” record containing the column name if it was changed using the Fluid API or ColumnAttribute, but the record value is an inner class in the EF part. Is it even possible?

I looked through several answers on this topic, but none of them take into account the configuration of the Fluid API.

PS the specific property I'm looking for is scalar if that can simplify things ...

+5
source share
1 answer

Column name

To get the name of a column, you must first get EdmPropertyassociated with that column in "structural space" ( SSpace). I provide the code for this below. If you have EdmProperty, the column name will be simple EdmProperty.Name:

string GetColumnName(DbContext context, PropertyInfo property) {
    return GetStructuralSpaceEdmProperty(context, property).Name;
}

Structural Space Property

This is based on the article . This article gives you enough information to compare with structural EntityType. I added a little at the end to do the actual mapping of the properties to get a EdmPropertyrepresenting column. As the article says, these APIs require ≥EntityFramework-6.1.

EdmProperty GetStructuralSpaceEdmProperty(DbContext context, PropertyInfo property) {
    IObjectContextAdapter adapter = context;
    var metadata = adapter.ObjectContext.MetadataWorkspace;

    // First, you map the Object Space to the Conceptual Space.
    var objectItemCollection = (ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace);
    var objectEntityType = metadata.GetItems<EntityType>(DataSpace.OSpace)
        .Single(oet => objectItemCollection.GetClrType(oet) == property.DeclaringType);
    // Note: we are assuming that CSpace and OSpace name their properties the
    // same instead of trying to use EFs own OSSpace mappings here.
    var conceptualEntityType = metadata.GetItems<EntityType>(DataSpace.CSpace)
        .Single(cet => objectEntityType.Name == cet.Name);
    var conceptualEdmProperty = conceptualEntityType.Properties
        .Single(ep => ep.Name == property.Name);

    // Then you map the conceptual space onto the structural space.
    var entitySet = metadata.GetItems<EntityContainer>(DataSpace.CSpace)
        .Single().EntitySets
        .Single(es => es.ElementType.Name == conceptualEntityType.Name);
    var entityMapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace)
        .Single().EntitySetMappings
        .Single(esm => esm.EntitySet == entitySet);
    // The entity may be split to different tables or fragments.
    var fragments = entityMapping.EntityTypeMappings
        .SelectMany(etm => etm.Fragments);
    var propertyMappings = fragments.SelectMany(f => f.PropertyMappings);
    // Normal properties will be "ScalarPropertyMapping".
    // Depending on what information you are seeking or your
    // model, you may be interested in other PropertyMapping.
    var structuralSpaceProperty = propertyMappings
        .OfType<ScalarPropertyMapping>()
        .Single(pm => pm.Property == conceptualEdmProperty).Column;

    return structuralSpaceProperty;
}

, EdmProperty , . , SQL Server EdmProperty.IsUnicode true NVARCHAR/NCHAR false VARCHAR/CHAR .

EF

. " 10 - Entity Framework" API, . DataSpace.OSpace " ", POD.net. DataSpace.SSpace " ", , , "" "SQL" , , , . DataSpace.CSpace " ", , , , " ", " ". DataSpace.OCSpace . , , , .net. DataSpace.CSSpace . , API ColumnAttribute.

API

API EF, -, , API EF. , . , , Enumerable.OfType<TResult> ScalarPropertyMapping , , ScalarPropertyMapping ScalarPropertyMapping. , MetadataWorkspace.GetItems<T>() , , , , EntityType. , EF , API.

+1

All Articles