Подтвердить что ты не робот

Получить имя таблицы базы данных из Entity Framework MetaData

Я пытаюсь найти способ получить базовое имя таблицы SQL для данного типа сущности. Я экспериментировал с запросами MetadataWorkspace, и, хотя я могу получить много информации из объекта или пространства для хранения, я не могу понять, как сопоставить между ними.

Так сказать, у меня есть тип в объектной модели Lookup - как найти в базе данных имя_таблицы (wws_lookups)?

Я могу запросить все объекты EntityType для CSpace и SSpace, и я могу видеть оба перечисленные правильно, но я не могу понять, как получить SSpace из CSpace.

Есть ли способ сделать это?

4b9b3361

Ответ 1

Я использую подход Nigel (извлечение имени таблицы из .ToTraceString()), но с некоторыми изменениями, потому что его код не будет работать, если таблица не находится в схеме SQL Server по умолчанию (dbo.{table-name}).

Я создал методы расширения для объектов DbContext и ObjectContext:

public static class ContextExtensions
{
    public static string GetTableName<T>(this DbContext context) where T : class
    {
        ObjectContext objectContext = ((IObjectContextAdapter) context).ObjectContext;

        return objectContext.GetTableName<T>();
    }

    public static string GetTableName<T>(this ObjectContext context) where T : class
    {
        string sql = context.CreateObjectSet<T>().ToTraceString();
        Regex regex = new Regex(@"FROM\s+(?<table>.+)\s+AS");
        Match match = regex.Match(sql);

        string table = match.Groups["table"].Value;
        return table;
    }
}

Подробнее здесь:
Entity Framework: получить сопоставленное имя таблицы из объекта

Ответ 2

РЕДАКТИРОВАТЬ Этот ответ теперь устарел из-за новой функции в EF 6.1: сопоставление между типами таблиц. Иди туда первым!

У меня была проблема с другими ответами, потому что у меня есть производный тип. Я получил этот метод (внутри моего контекстного класса), чтобы работать - у меня только один уровень наследования в моей модели на данный момент

private readonly static Dictionary<Type, EntitySetBase> _mappingCache 
       = new Dictionary<Type, EntitySetBase>();

private EntitySetBase GetEntitySet(Type type)
{
    //If it a proxy, get the entity type associated with it
    type = ObjectContext.GetObjectType(type);

    if (_mappingCache.ContainsKey(type))
        return _mappingCache[type];

    string baseTypeName = type.BaseType.Name;
    string typeName = type.Name;

    ObjectContext octx = _ObjectContext;
    var es = octx.MetadataWorkspace
                    .GetItemCollection(DataSpace.SSpace)
                    .GetItems<EntityContainer>()
                    .SelectMany(c => c.BaseEntitySets
                                    .Where(e => e.Name == typeName 
                                    || e.Name == baseTypeName))
                    .FirstOrDefault();

    if (es == null)
        throw new ArgumentException("Entity type not found in GetEntitySet", typeName);

    // Put es in cache.
    _mappingCache.Add(type, es);

    return es;
}

internal String GetTableName(Type type)
{
    EntitySetBase es = GetEntitySet(type);

    //if you are using EF6
    return String.Format("[{0}].[{1}]", es.Schema, es.Table);

    //if you have a version prior to EF6
    //return string.Format( "[{0}].[{1}]", 
    //        es.MetadataProperties["Schema"].Value, 
    //        es.MetadataProperties["Table"].Value );
}

internal Type GetObjectType(Type type)
{
    return System.Data.Entity.Core.Objects.ObjectContext.GetObjectType(type);
}

NB. Существуют планы по улучшению API метаданных, и если это не дает того, чего мы хотим, мы можем взглянуть на EF Code First Mapping между типами и таблицами.

Ответ 3

Нет, к сожалению, невозможно использовать API-интерфейсы метаданных для перехода к табло-имени для данного объекта.

Это связано с тем, что метаданные сопоставления не являются общедоступными, поэтому нет возможности перейти с C-Space на S-Space с помощью API-интерфейсов EF.

Если вам действительно нужно это сделать, вы всегда можете создать карту самостоятельно, разыгрывая MSL. Это не для слабонервных, но это должно быть возможно, если вы не используете QueryViews (которые невероятно редки), после чего он для всех целей и задач невозможно (вам придется разбирать ESQL... argh!)

Алекс Джеймс

Microsoft.

Ответ 4

Есть способ удалить данные с помощью EF, не загружая их вначале. Я описал его чуть более задерживаю в: http://nigelfindlater.blogspot.com/2010/04/how-to-delete-objects-in-ef4-without.html

Хитрость заключается в том, чтобы включить IQueriable в ObjectQuery и использовать метод ToTraceString. Затем отредактируйте полученную строку sql. Он работает, но вам нужно быть осторожным, потому что вы обходите механизмы, которые EF имеет для поддержания зависимостей и недочетов. Но по соображениям производительности я считаю, что это нормально...

получайте удовольствие...

Найджел...

    private string GetClause<TEntity>(IQueryable<TEntity> clause) where TEntity : class 
    { 
        string snippet = "FROM [dbo].["; 

        string sql = ((ObjectQuery<TEntity>)clause).ToTraceString(); 
        string sqlFirstPart = sql.Substring(sql.IndexOf(snippet)); 

        sqlFirstPart = sqlFirstPart.Replace("AS [Extent1]", ""); 
        sqlFirstPart = sqlFirstPart.Replace("[Extent1].", ""); 

        return sqlFirstPart; 
    } 

   public void DeleteAll<TEntity>(IQueryable<TEntity> clause) where TEntity : class 
    { 
        string sqlClause = GetClause<TEntity>(clause); 
        this.context.ExecuteStoreCommand(string.Format(CultureInfo.InvariantCulture, "DELETE {0}", sqlClause)); 
    } 

Ответ 5

Если вы используете шаблон T4 для классов POCO, вы можете получить его, изменив шаблон T4. См. Фрагмент:

<#  
////////////////////////////////////////////////////////////////////////////////
region.Begin("Custom Properties");

string xPath = "//*[@TypeName='" + entity.FullName + "']";
XmlDocument doc = new XmlDocument();
doc.Load(inputFile);

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2008/10/edmx");

XmlNode item;
XmlElement root = doc.DocumentElement;
item = root.SelectSingleNode(xPath);

#>
    //<#= xPath #>
    //<#= entity.FullName #>
    //<#= (item == null).ToString() #>

<# if (item != null) #>
// Table Name from database
public string TableName { get { return "<#= item.ChildNodes[0].Attributes["StoreEntitySet"].Value #>"; } }
<#

region.End();

////////////////////////////////////////////////////////////////////////////////

Ответ 6

Если вы делаете codefirst в EF6, вы можете просто добавить что-то вроде следующего к вашему классу dbcontext.

    public string GetTableName(Type entityType)
    {
        var sql = Set(entityType).ToString();
        var regex = new Regex(@"FROM \[dbo\]\.\[(?<table>.*)\] AS");
        var match = regex.Match(sql);

        return match.Groups["table"].Value;
    }

Ответ 7

Большинство ответов здесь не работают с производными классами. Этот делает. И дает вам схему тоже. Я объединил здесь ответы и немного их улучшил (убрав такие вещи, как First() и Single() и преобразовав их в такие, как Where() и SelectMany(), и вернув имя схемы).

Это работает с EF 6. 1+

// This can return multiple values because it is possible to have one entity correspond to multiple tables when doing entity splitting.
    public static IEnumerable<string> GetTableName<T>(this DbContext context)
    {
        var type = typeof(T);

        var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace;

        // Get the part of the model that contains info about the actual CLR types
        var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace));

        // Get the entity type from the model that maps to the CLR type
        var entityType = metadata
                .GetItems<EntityType>(DataSpace.OSpace)
                .Single(e => objectItemCollection.GetClrType(e) == type);

        // Get the entity set that uses this entity type
        var entitySet = metadata.GetItems(DataSpace.CSpace).Where(x => x.BuiltInTypeKind == BuiltInTypeKind.EntityType).Cast<EntityType>().Single(x => x.Name == entityType.Name);

        // Find the mapping between conceptual and storage model for this entity set
        var entitySetMappings = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace).Single().EntitySetMappings.ToList();

        // Find the storage entity sets (tables) that the entity is mapped
        //EntitySet table;

        var fragments = new List<MappingFragment>();

        var mappings = entitySetMappings.Where(x => x.EntitySet.Name == entitySet.Name);

        //if (mappings.Count() > 0)
        //return mappings.SelectMany(m => m.EntityTypeMappings.SelectMany(em => em.Fragments)).ToList();

        fragments.AddRange(mappings.SelectMany(m => m.EntityTypeMappings.SelectMany(em => em.Fragments)));

        fragments.AddRange(entitySetMappings.Where(x => x.EntityTypeMappings.Where(y => y.EntityType != null).Any(y => y.EntityType.Name == entitySet.Name))
            .SelectMany(m => m.EntityTypeMappings.Where(x => x.EntityType != null && x.EntityType.Name == entityType.Name).SelectMany(x => x.Fragments)));

        //if (mapping != null)
        //return mapping.EntityTypeMappings.Where(x => x.EntityType != null).Single(x => x.EntityType.Name == entityType.Name).Fragments;

        fragments.AddRange(entitySetMappings.Where(x => x.EntityTypeMappings.Any(y => y.IsOfEntityTypes.Any(z => z.Name == entitySet.Name)))
        .SelectMany(m => m.EntityTypeMappings.Where(x => x.IsOfEntityTypes.Any(y => y.Name == entitySet.Name)).SelectMany(x => x.Fragments)));

        //var fragments = getFragments();

        // Return the table name from the storage entity set

        var tableNames = fragments.Select(f =>
        {
            var schemaName = f.StoreEntitySet.Schema;
            var tableName = (string)f.StoreEntitySet.MetadataProperties["Table"].Value ?? f.StoreEntitySet.Name;
            var name = $"[{schemaName}].[{tableName}]";
            return name;
        }).Distinct().ToList();

        return tableNames;
    }

Ответ 8

Возможное обходное решение (не большое, но не альтернативы...):

var sql = Context.EntitySetName.ToTraceString();

... затем проанализируйте SQL, который должен быть довольно простым.

Ответ 9

Вот что я смог придумать с помощью LINQ to XML. Код также получает сопоставления для имен столбцов.

var d = XDocument.Load("MyModel.edmx");
XNamespace n = "http://schemas.microsoft.com/ado/2008/09/mapping/cs";
var l = (from etm in d.Descendants()
            where etm.Name == n + "EntityTypeMapping"
            let s = etm.Attribute("TypeName").Value
            select new
            {
                Name = s.Remove(0, s.IndexOf(".") + 1).Replace(")", ""),
                Table = etm.Element(n + "MappingFragment").Attribute("StoreEntitySet").Value,
                Properties = (from sp in etm.Descendants(n + "ScalarProperty")
                            select new
                            {
                                Name = sp.Attribute("Name").Value,
                                Column = sp.Attribute("ColumnName").Value
                            }).ToArray()
            }).ToArray();

Ответ 11

EF 6.1, сначала код:

public static string GetTableName<T>(this DbContext context) where T : class
{
    ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
    return objectContext.GetTableName(typeof(T));
}

public static string GetTableName(this DbContext context, Type t)
{
    ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
    return objectContext.GetTableName(t);
}

private static readonly Dictionary<Type,string> TableNames = new Dictionary<Type, string>();

public static string GetTableName(this ObjectContext context, Type t)
    {
        string result;

        if (!TableNames.TryGetValue(t, out result))
        {
            lock (TableNames)
            {
                if (!TableNames.TryGetValue(t, out result))
                {

                    string entityName = t.Name;

                    ReadOnlyCollection<EntityContainerMapping> storageMetadata = context.MetadataWorkspace.GetItems<EntityContainerMapping>(DataSpace.CSSpace);

                    foreach (EntityContainerMapping ecm in storageMetadata)
                    {
                        EntitySet entitySet;
                        if (ecm.StoreEntityContainer.TryGetEntitySetByName(entityName, true, out entitySet))
                        {
                            if (String.IsNullOrEmpty(entitySet.Schema))
                            {
                                result = entitySet.Table;
                                break;
                            }


                            //we must recognize if we are under SQL Server Compact version, which does not support multiple schemas
                            //SQL server compact does not support schemas, entity framework sets entitySet.Schema set to "dbo", anyway
                            //the System.Data.Entity.Infrastructure.TableExistenceChecker.GetTableName() returns only table name
                            //schema is (not) added by the overrides of the method AnyModelTableExistsInDatabase
                            //the SqlCeTableExistenceChecker has the knowledge that there is no metadata schema needed
                            //the SqlTableExistenceChecker has the knowledge that there is metadata with schema, which should be added to the table names

                            var entityConnection = (System.Data.Entity.Core.EntityClient.EntityConnection) context.Connection;

                            DbConnection storeConnection = entityConnection.StoreConnection;

                            if (storeConnection != null && "SqlCeConnection".Equals(storeConnection.GetType().Name, StringComparison.OrdinalIgnoreCase))
                            {
                                result = entitySet.Table;
                                break;
                            }

                            result = entitySet.Schema  + "." + entitySet.Table;
                            break;
                        }
                    }

                    TableNames.Add(t,result);
                }
            }
        }

        return result;
    }

Ответ 12

Вот еще один способ найти имя таблицы. Это немного странно, но работает. VB:

For Each Table In northwind.MetadataWorkspace.GetItemCollection(New System.Data.Metadata.Edm.DataSpace)
        'adds table name to a list of strings all table names in EF have the project namespace in front of it.'
        If Table.ToString.Contains("namespace of project") then
            'using substring to remove project namespace from the table name.'
            TableNames.Add(Table.ToString.Substring("length of namespace name"))      
        End If
    Next

Ответ 13

Вы можете попробовать расширение MappingAPI: https://efmappingapi.codeplex.com/

Очень удобно использовать

context.Db<YourEntityType>().TableName

Ответ 14

Используя EF Core с сервером SQL, это так же просто, как:

_context.Model.FindEntityType(YOUR_VAR_TYPE).SqlServer().TableName

Ответ 15

Вот версия, предполагающая, что у вас есть контекст, и у вас есть выделенный объект в памяти, который вам нужно найти для имени реальной таблицы.

    
    public static class ObjectContextExtentions
    {
        public static string TableNameFor(this ObjectContext context, ObjectStateEntry entry)
        {
            var generic =
                context.GetType().GetProperties().ToList().First(p => p.Name == entry.EntityKey.EntitySetName);
            var objectset = generic.GetValue(context, null);

            var method = objectset.GetType().GetMethod("ToTraceString");
            var sql = (String)method.Invoke(objectset, null);

            var match = Regex.Match(sql, @"FROM\s+\[dbo\]\.\[(?<TableName>[^\]]+)\]", RegexOptions.Multiline);
            if (match.Success)
            {
                return match.Groups["TableName"].Value;
            }

            throw new ArgumentException("Unable to find Table name.");
        } 
    }

Ответ 16

На самом деле, у меня была одна и та же проблема, и я создал абстрактный фрагмент кода, который дает вам два Dictionary<string,List<string>> ($ table_name, $column_name_list). Во-первых, есть таблица таблиц + столбцов, вторая имеет локальные объекты EF + свойства

Конечно, вы можете добавить дополнительные проверки против типа данных, btw imho, которые заставили бы вас писать безумно сложный код.

P & L

P.S. Извините за сжатый стиль, я фанатик лямбды

using (EFModelContext efmc = new EFModelContext("appConfigConnectionName"))
{
    string schemaName = "dbo";
    string sql = @"select o.name + '.' + c.name
               from sys.all_objects o 
                inner join sys.schemas s on s.schema_id = o.schema_id
                inner join sys.all_columns c on c.object_id = o.object_id
               where Rtrim(Ltrim(o.type)) in ('U') and s.name = @p0";

    Dictionary<string, List<string>> dbTableColumns = new Dictionary<string, List<string>>();

    efmc.Database.SqlQuery<string>(sql, schemaName).Select(tc =>
    {
        string[] splitted = System.Text.RegularExpressions.Regex.Split(tc, "[.]");
        return new { TableName = splitted[0], ColumnName = splitted[1] };
    }).GroupBy(k => k.TableName, k => k.ColumnName).ToList().ForEach(ig => dbTableColumns.Add(ig.Key, ig.ToList()));

    Dictionary<string, List<string>> efTableColumns = new Dictionary<string, List<string>>();

    efTableColumns = ((IObjectContextAdapter)uc).ObjectContext.MetadataWorkspace
                 .GetItems(DataSpace.SSpace).OfType<EntityType>()
                 .ToDictionary( eft => eft.MetadataProperties
                                     .First(mp => mp.Name == "TableName").Value.ToString(),
                                eft => eft.Properties.Select(p => p.Name).ToList());
}

Ответ 17

Алекс прав - это печальное ограничение в API метаданных. Я должен просто загрузить MSL в качестве документа XML и выполнять поиск объектов S-пространства при обработке моей модели C-пространства.

Ответ 18

Используя EF5 и бит litle бит, что-то вроде следующего должно сделать трюк:

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

Ответ 19

Для EF6, смешение/сжатие кода из других ответов здесь и вокруг (VB, извините):

    Public Function getDBTableName(data As myDataModel, ByVal entity As Object) As String
        Dim context = CType(data, IObjectContextAdapter).ObjectContext
        Dim sName As String = entity.GetType.BaseType.Name 'use BaseType to avoid proxy names'
        Dim map = context.MetadataWorkspace.GetItems(Of EntityContainerMapping)(DataSpace.CSSpace).FirstOrDefault

        Return (From esmap In map.EntitySetMappings 
                Select esmap.EntityTypeMappings.First(
                    Function(etm) 
                     etm.EntityType.Name = sName
                   ).Fragments.First.StoreEntitySet.Name).FirstOrDefault
        'TODO: use less .first everywhere but filter the correct ones'
    End Function

Он работает для db-first.
Относительно легко понять следующий файл .edmx.

Ответ 20

Копируем мой ответ на другой вопрос здесь.

Если кто-то все еще смотрит, вот как я это сделал. Это метод расширения для DBContext, который принимает тип и возвращает имена физических столбцов и их свойства.

Это использует контекст объекта для получения списка физических столбцов, а затем использует свойство метаданных "PreferredName", чтобы сопоставить каждому столбцу его свойство.

Поскольку он использует контекст объекта, он инициирует соединение с базой данных, поэтому первый запуск будет медленным в зависимости от сложности контекста.

public static IDictionary<String, PropertyInfo> GetTableColumns(this DbContext ctx, Type entityType)
{
    ObjectContext octx = (ctx as IObjectContextAdapter).ObjectContext;
    EntityType storageEntityType = octx.MetadataWorkspace.GetItems(DataSpace.SSpace)
        .Where(x => x.BuiltInTypeKind == BuiltInTypeKind.EntityType).OfType<EntityType>()
        .Single(x => x.Name == entityType.Name);

    var columnNames = storageEntityType.Properties.ToDictionary(x => x.Name,
        y => y.MetadataProperties.FirstOrDefault(x => x.Name == "PreferredName")?.Value as string ?? y.Name);

    return storageEntityType.Properties.Select((elm, index) =>
            new {elm.Name, Property = entityType.GetProperty(columnNames[elm.Name])})
        .ToDictionary(x => x.Name, x => x.Property);
}

Чтобы использовать его, просто создайте вспомогательный статический класс и добавьте выше функцию; то это так же просто, как вызов

var tabCols = context.GetTableColumns(typeof(EntityType));

Ответ 21

В случае использования Entity Framework Core 2. 0+ вы можете легко получить реляционные метаданные, используя предоставленные API.

foreach (var entityType in dbContext.Model.GetEntityTypes())
{
    var tableName = entityType.Relational().TableName;
    foreach (var propertyType in entityType.GetProperties())
    {
        var columnName = propertyType.Relational().ColumnName;
    }
}

Для использования метода Relational() необходимо установить пакет Nuget Microsoft.EntityFrameworkCore.Relational.

Ответ 22

Добавление другого ответа для особого случая, когда вы используете аннотации, чтобы явно указать EF, какое имя таблицы использовать. Например, если у вас есть:

[Table("tblCompany")]
public class Company
{
}

Вы можете легко получить доступ к аннотации TableAttribute чтобы найти имя таблицы:

((System.ComponentModel.DataAnnotations.Schema.TableAttribute)typeof(YourNamespace.BO.Company).GetCustomAttribute(typeof(System.ComponentModel.DataAnnotations.Schema.TableAttribute))).Name

которая является tblCompany для данного образца.

Как готовый метод:

using System.Reflection;
using System.ComponentModel.DataAnnotations.Schema;

public static string GetTableName<T>() {
    return ((TableAttribute)typeof(T).GetCustomAttribute(typeof(TableAttribute))).Name;
}

(Я знаю, что это не поможет ОП, но, учитывая название вопроса, здесь могут оказаться люди, которые могут искать этот ответ.)

Ответ 23

Если вам нужен быстрый и грязный способ получить имя таблицы (а вам это не нужно в коде приложения), вы можете посмотреть на XML, сгенерированный для вашего Model.edmx. Найдите вашу сущность в разделе edmx: Mappings, и строка: MappingFragment StoreEntitySet = "YourTableName" даст вам фактическое имя таблицы.