Getting mapped column names of properties in entity framework

c# entity-framework sql

Question

Entity Framework 6 is what I use in my project. I possess these things:

   public class Person
    {
        [Key]
        public int Id { get; set; }

        public string Name { get; set; }

        public virtual ICollection<PersonRight> PersonRights { get; set; }
    }

and

 public class PersonRight
    {
        [Key]
        public int Id { get; set; }

        public string Name { get; set; }
    }

The database shows the following when I insert a person object with filled-in PersonRights:

entity table for Person:

dbo.People with columns Id, Name

table for the entity PersonRights

dbo.PersonRights with columns Id, Name, Person_Id

The virtual keyword, which enables the lazy loading feature, prevents the PersonRights property from being filled when I load a person from a database, but that's acceptable.

After that, it works well when I retrieve the PersonRights for the person object.

The problem is that because the PersonRight entity lacks a navigation property, the entity framework must understand which database columns define the boundaries of those two attributes. A foreign key in the database links the PersonRights and People tables:

FK_dbo.PersonRights_dbo.People_Person_Id

Is there a way to discover the name of the column that connects those two properties? Is there a way to obtain "Person Id" in code?

There is a method for determining which table a database entity is bound to:

http://www.codeproject.com/Articles/350135/Entity-Framework-Get-mapped-table-name-from-an-ent

Many thanks for your responses.

EDIT:

I discovered that the column name, property, is located here:

  var items = ((IObjectContextAdapter)dbContext).ObjectContext.MetadataWorkspace.GetItems(DataSpace.CSSpace);

yet I'm still unable to access it; the strange thing is that when I select the first item from this collection, it indicates to me that its type isSystem.Data.Entity.Core.Mapping.StorageEntityContainerMapping however, when I read it piece by piece, all of a sudden the type isSystem.Data.Entity.Metadata.Edm.GlobalItem ...

How do I go to theSystem.Data.Entity.Core.Mapping.StorageEntityContainerMapping item where the collection is also I must give the column a name.AssociationSetMappings ??

1
10
11/23/2013 2:32:09 PM

Accepted Answer

From the storage model, you can access the real text "Person Id," but you cannot recognize that property or column as the foreign key. You would need Person Id to be present in the conceptual model for that to happen. Here's how you would obtain it from the storage metadata: I'm still not sure why you wouldn't want it in the model.

using ( var context = new YourEntities() )
{
  var objectContext = ( ( IObjectContextAdapter )context ).ObjectContext;
  var storageMetadata = ( (EntityConnection)objectContext.Connection ).GetMetadataWorkspace().GetItems( DataSpace.SSpace );
  var entityProps = ( from s in storageMetadata where s.BuiltInTypeKind == BuiltInTypeKind.EntityType select s as EntityType );
  var personRightStorageMetadata = ( from m in entityProps where m.Name == "PersonRight" select m ).Single();
  foreach ( var item in personRightStorageMetadata.Properties )
  {
      Console.WriteLine( item.Name );
  }
}
18
11/27/2013 2:49:26 PM

Popular Answer

For EF6 Only in could I locate the mappingsDataSpace.CSSpace (EntityTypeMapping tables will be mapped to entities, andScalarPropertyMapping will convert scalar attributes into columns):

using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;

// ...

using ( var db = new YourContext() )
{
  var metadataWorkspace = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)db)
  .ObjectContext.MetadataWorkspace;

  var itemCollection = ((StorageMappingItemCollection)metadataWorkspace
  .GetItemCollection(DataSpace.CSSpace));

  var entityMappings = itemCollection.OfType<EntityContainerMapping>().Single()
  .EntitySetMappings.ToList();

  var entityMapping = (EntityTypeMapping)entityMappings
    .Where(e => e.EntitySet.ElementType.FullName == typeof(TEntity).FullName)
    //or .Where(e => e.EntitySet.ElementType.Name == "YourEntityName")
    .Single().EntityTypeMappings.Single();

  var fragment = entityMapping.Fragments.Single();
  var dbTable = fragment.StoreEntitySet;

  Console.WriteLine($"Entity {entityMapping.EntityType.FullName} is mapped to table [{dbTable.Schema}].[{dbTable.Name}]");

  var scalarPropsMap = entityMapping.Fragments.Single()
  .PropertyMappings.OfType<ScalarPropertyMapping>();

  foreach(var prop in scalarPropsMap)
    Console.WriteLine($"Property {prop.Property.Name} maps to Column {prop.Column.Name}");

}

I use the code above out of curiosity becauseSystem.Data.SqlClient.SqlBulkCopy required mapping between database columns and entity characteristics.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow