在我的项目中,我使用Entity Framework 6。 我有这些实体:
public class Person
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<PersonRight> PersonRights { get; set; }
}
和
public class PersonRight
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
当我插入填充了PersonRights的person对象时,它在数据库中看起来像这样:
人员实体表:
dbo.People with columns Id, Name
PersonRights实体的表
dbo.PersonRights with columns Id, Name, Person_Id
当我从数据库加载一个人时,它没有填充PersonRights属性,因为虚拟关键字增加了延迟加载功能 - 而且没关系。
然后我得到了person对象的PersonRights,它也可以正常工作。
问题是,由于PersonRight实体中没有导航属性,因此实体框架必须知道数据库中的哪些列是有界的那两个属性。 在数据库中,ther是连接PersonRights和People表的外键:
FK_dbo.PersonRights_dbo.People_Person_Id
问题是:是否有任何方法可以获取列名称,这两个属性是否已连接? 如何在代码中获取字符串“Person_Id”?
有一种方法可以找出哪个表是数据库中的实体:
http://www.codeproject.com/Articles/350135/Entity-Framework-Get-mapped-table-name-from-an-ent
非常感谢您的回答:)
编辑:
我发现列名称属性在这里:
var items = ((IObjectContextAdapter)dbContext).ObjectContext.MetadataWorkspace.GetItems(DataSpace.CSSpace);
但是我仍然无法达到它,问题很奇怪,当我从这个集合中得到第一个项目时,它告诉我它的类型是System.Data.Entity.Core.Mapping.StorageEntityContainerMapping
但是当我突然通过foreach经历它时,类型是System.Data.Entity.Metadata.Edm.GlobalItem
...
如何访问System.Data.Entity.Core.Mapping.StorageEntityContainerMapping
项,其中也是我需要的集合,以获取名为 - AssociationSetMappings
的列_ ??
答案 0 :(得分:16)
您可以从存储模型中获取实际字符串“Person_Id”,但无法将该属性/列标识为外键。为此,您需要Person_Id存在于概念模型中。我仍然不太明白为什么你不想在模型中使用它,但是这是你如何从存储元数据中获取它:
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 );
}
}
答案 1 :(得分:0)
对于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}");
}
出于好奇,我使用上面的代码,因为System.Data.SqlClient.SqlBulkCopy
需要在实体属性和表列之间进行映射。