简体   繁体   English

在实体框架中获取属性的映射列名

[英]Getting mapped column names of properties in entity framework

in my project I use Entity Framework 6. I have these entities:在我的项目中,我使用实体框架 6。我有这些实体:

   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; }
    }

When I insert a person object with filled in PersonRights it looks like this in the database:当我插入一个填充了 PersonRights 的 person 对象时,它在数据库中看起来像这样:

table for Person entity: Person 实体表:

dbo.People with columns Id, Name

table for PersonRights entity PersonRights 实体的表

dbo.PersonRights with columns Id, Name, Person_Id

when I load a person from a database it hasnt filled PersonRights property because of the virtual keyword which is enabeling the lazy loading feature - and its okay.当我从数据库加载一个人时,它没有填充 PersonRights 属性,因为启用了延迟加载功能的 virtual 关键字 - 没关系。

Then I get the PersonRights for the person object and it also works fine.然后我获得了 person 对象的 PersonRights 并且它也可以正常工作。

The thing is, since there is no navigation property in PersonRight entity, the entity framework must know by which columns in the database are those two properties bounded.问题是,由于 PersonRight 实体中没有导航属性,因此实体框架必须知道数据库中的哪些列是这两个属性的边界。 In database ther is a foreign key connecting PersonRights and People tables:在数据库中有一个连接 PersonRights 和 People 表的外键:

FK_dbo.PersonRights_dbo.People_Person_Id

The question is : Is there any way how to get the column name by which are those two properties connected?问题是:有什么方法可以获取连接这两个属性的列名? Any way how to get the string "Person_Id" in code?任何方式如何在代码中获取字符串“Person_Id”?

There is a way how to find out to which table is an entity bounded in database :有一种方法可以找出哪个表是数据库中的实体:

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

thanks a lot for your answers :)非常感谢您的回答:)

EDIT:编辑:

Well I found out that the column name propety is here:好吧,我发现列名属性在这里:

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

but I still cant reach it, the problem is weird, when I get first item from this collection it shows me that its type is System.Data.Entity.Core.Mapping.StorageEntityContainerMapping but when I go through it by foreach suddenly the type is System.Data.Entity.Metadata.Edm.GlobalItem ...但我仍然无法访问它,问题很奇怪,当我从这个集合中获取第一项时,它显示它的类型是System.Data.Entity.Core.Mapping.StorageEntityContainerMapping但是当我突然通过 foreach 遍历它时,类型是System.Data.Entity.Metadata.Edm.GlobalItem ...

How can I access the System.Data.Entity.Core.Mapping.StorageEntityContainerMapping item where is also the collection I need to get the column named - AssociationSetMappings ??如何访问System.Data.Entity.Core.Mapping.StorageEntityContainerMapping项目,其中也是我需要获取名为 - AssociationSetMappings的列的集合?

You can get to the actual string "Person_Id" from the storage model, but you cannot identify that property/column as the foreign key.您可以从存储模型中获取实际字符串“Person_Id”,但您无法将该属性/列标识为外键。 For that you would need Person_Id to exist in the conceptual model.为此,您需要 Person_Id 存在于概念模型中。 I still don't quite understand why you wouldn't want it in the model, but here's how you would get it from the storage metadata:我仍然不太明白为什么你不想在模型中使用它,但这里是你如何从存储元数据中获取它的方法:

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 );
  }
}

For EF6 I could only find the mappings in DataSpace.CSSpace ( EntityTypeMapping will map entities to tables, and ScalarPropertyMapping will map scalar properties to columns):对于EF6我只能在DataSpace.CSSpace找到映射( EntityTypeMapping将实体映射到表, ScalarPropertyMapping将标量属性映射到列):

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}");

}

Out of curiosity I use the code above because System.Data.SqlClient.SqlBulkCopy requires mapping between entity properties and table columns.出于好奇,我使用了上面的代码,因为System.Data.SqlClient.SqlBulkCopy需要实体属性和表列之间的映射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM