使用 EF5 和一点点反射,类似下面的东西应该可以解决问题:
using System;
using System.Collections;
using System.Data.Entity.Infrastructure;
using System.Data.Metadata.Edm;
using System.Linq;
using System.Reflection;
namespace EFHelpers {
public class EFMetadataMappingHelper {
public static string GetTableName(MetadataWorkspace metadata, DbEntityEntry entry) {
var entityType = entry.Entity.GetType();
var objectType = getObjectType(metadata, entityType);
var conceptualSet = getConceptualSet(metadata, objectType);
var storeSet = getStoreSet(metadata, conceptualSet);
var tableName = findTableName(storeSet);
return tableName;
}
private static EntitySet getStoreSet(MetadataWorkspace metadata, EntitySetBase entitySet) {
var csSpace = metadata.GetItems(DataSpace.CSSpace).Single();
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
var entitySetMaps = (ICollection)csSpace.GetType().GetProperty("EntitySetMaps", flags).GetValue(csSpace, null);
object mapping = null;
foreach (var map in entitySetMaps) {
var set = map.GetType().GetProperty("Set", flags).GetValue(map, null);
if (entitySet == set) {
mapping = map;
break;
}
}
var m_typeMappings = ((ICollection)mapping.GetType().BaseType.GetField("m_typeMappings", flags).GetValue(mapping)).OfType<object>().Single();
var m_fragments = ((ICollection)m_typeMappings.GetType().BaseType.GetField("m_fragments", flags).GetValue(m_typeMappings)).OfType<object>().Single();
var storeSet = (EntitySet) m_fragments.GetType().GetProperty("TableSet", flags).GetValue(m_fragments, null);
return storeSet;
}
private static string findTableName(EntitySet storeSet) {
string tableName = null;
MetadataProperty tableProperty;
storeSet.MetadataProperties.TryGetValue("Table", true, out tableProperty);
if (tableProperty == null || tableProperty.Value == null)
storeSet.MetadataProperties.TryGetValue("http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator:Table", true, out tableProperty);
if (tableProperty != null)
tableName = tableProperty.Value as string;
if (tableName == null)
tableName = storeSet.Name;
return tableName;
}
private static EntityType getObjectType(MetadataWorkspace metadata, Type entityType) {
var objectItemCollection = (ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace);
var edmEntityType = metadata
.GetItems<EntityType>(DataSpace.OSpace)
.First(e => objectItemCollection.GetClrType(e) == entityType);
return edmEntityType;
}
private static EntitySetBase getConceptualSet(MetadataWorkspace metadata, EntityType entityType) {
var entitySetBase = metadata
.GetItems<EntityContainer>(DataSpace.CSpace)
.SelectMany(a => a.BaseEntitySets)
.Where(s => s.ElementType.Name == entityType.Name)
.FirstOrDefault();
return entitySetBase;
}
}
}
调用它是这样的:
public string GetTableName(DbContext db, DbEntityEntry entry) {
var metadata = ((IObjectContextAdapter)db).ObjectContext.MetadataWorkspace;
return EFMetadataMappingHelper.GetTableName(metadata, entry);
}