Entity Framework - как получить столбцы? - PullRequest
18 голосов
/ 19 мая 2011

Я хочу получить список имен столбцов, типов и того, является ли столбец PK объекта таблицы в Entity Framework.

Как мне сделать это в C # (4.0) (в идеале в общем)?

Победившим ответом будет тот, который делает это эффективно и, что важнее всего, в общем.

Ответы [ 7 ]

10 голосов
/ 22 мая 2011

Понял - я использовал запрос отражения на основе linq:

IEnumerable<FieldList> properties = from p in typeof(T).GetProperties()
                                    where (from a in p.GetCustomAttributes(false)
                                    where a is EdmScalarPropertyAttribute   
                                    select true).FirstOrDefault()

Sorted!Спасибо за все предложения.

FYI - Я создаю динамическое предложение where с использованием LINQ, динамические лямбда-выражения для построения, например, поиск, который по умолчанию будет автоматически выполнять поиск по всем столбцам.Но мне также нужно было проверить имена столбцов, потому что я разрешаю это переопределять, и эти вызовы будут выполняться через пост jjascript ajax, вход которого не может быть доверенным - поэтому мне нужно было проверить имена столбцов.выше, чтобы поместить результаты в пользовательский объект со свойствами под названием FieldName, FieldType, PrimaryKey.Та дааа.

Настройте его далее с помощью

IEnumerable<FieldList> properties = from p in typeof(T).GetProperties()
                                    where (from a in p.GetCustomAttributes(false)
                                    where a is EdmScalarPropertyAttribute
                                    select true).FirstOrDefault()
                                    select new FieldList
                                    {
                                       FieldName = p.Name,
                                       FieldType = p.PropertyType,
                                       FieldPK = p.GetCustomAttributes(false).Where(a => a is EdmScalarPropertyAttribute && ((EdmScalarPropertyAttribute)a).EntityKeyProperty).Count() > 0
                                     };    
7 голосов
/ 28 мая 2015

если вы хотите только имена столбцов, я получил лучший ответ:
var properties = (from t in typeof(YourTableName).GetProperties() select t.Name).ToList(); var name= properties[0];

5 голосов
/ 26 июня 2013

Если вы не хотите использовать отражение, см. Ответ здесь .Замените имя сущности ниже на ваше имя сущности

var cols = from meta in ctx.MetadataWorkspace.GetItems(DataSpace.CSpace)
                       .Where(m=> m.BuiltInTypeKind==BuiltInTypeKind.EntityType)
                    from p in (meta as EntityType).Properties
                       .Where(p => p.DeclaringType.Name == "EntityName")
                   select new
                      {
                       PropertyName = p.Name,
                       TypeUsageName = p.TypeUsage.EdmType.Name, //type name
                       Documentation = p.Documentation != null ?               
                                       p.Documentation.LongDescription : null //if primary key
        };
1 голос
/ 10 августа 2018
typeof(TableName).GetProperties().Select(x => x.Name).ToList();
1 голос
/ 18 сентября 2017

Если кто-то еще смотрит, вот как я это сделал.Это метод расширения для 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));
0 голосов
/ 19 мая 2011

Если вы используете DB First или Model First, откройте файл .edmx EF, созданный в текстовом редакторе.Это просто файл XML, и он содержит все, что вам нужноВот пример из моей модели.Обратите внимание, что я использую драйвер Oracle EF, поэтому ваш не будет выглядеть идентично (но он должен быть довольно близок).

        <EntityType Name="STRATEGIC_PLAN">
          <Key>
            <PropertyRef Name="Id" />
          </Key>
          <Property Type="Decimal" Name="Id" Nullable="false" Precision="8" Scale="0" annotation:StoreGeneratedPattern="None" />
          <Property Type="Decimal" Name="CreatedById" Nullable="false" Precision="8" Scale="0" />
          <Property Type="DateTime" Name="CreatedDate" Nullable="false" />
          <Property Type="Decimal" Name="DepartmentId" Nullable="false" Precision="4" Scale="0" />
          <Property Type="String" Name="Name_E" Nullable="false" MaxLength="2000" FixedLength="false" Unicode="false" />
          <Property Type="String" Name="Name_F" MaxLength="2000" FixedLength="false" Unicode="false" />
          <Property Type="Decimal" Name="UpdatedById" Precision="8" Scale="0" />
          <Property Type="DateTime" Name="UpdatedDate" />
          <Property Type="DateTime" Name="Timestamp" Nullable="false" Precision="6" annotation:StoreGeneratedPattern="Computed" />
          <NavigationProperty Name="AnnualPlans" Relationship="StrategicPlanningModel.R_51213" FromRole="STRATEGIC_PLAN" ToRole="STRAT_ANNUAL_PLAN" />
          <NavigationProperty Name="Department" Relationship="StrategicPlanningModel.R_51212" FromRole="STRATEGIC_PLAN" ToRole="DEPARTMENT" />
          <NavigationProperty Name="CreatedBy" Relationship="StrategicPlanningModel.R_51210" FromRole="STRATEGIC_PLAN" ToRole="STAFF" />
          <NavigationProperty Name="UpdatedBy" Relationship="StrategicPlanningModel.R_51211" FromRole="STRATEGIC_PLAN" ToRole="STAFF" />
          <Property Type="String" Name="Desc_E" MaxLength="2000" FixedLength="false" Unicode="false" />
          <Property Type="String" Name="Desc_F" MaxLength="2000" FixedLength="false" Unicode="false" />
          <NavigationProperty Name="Goals" Relationship="StrategicPlanningModel.R_51219" FromRole="STRATEGIC_PLAN" ToRole="STRATEGIC_PLAN_GOAL" />
        </EntityType>

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

0 голосов
/ 19 мая 2011

У меня нет примера кода для вас, но просто для того, чтобы вы указали в правильном направлении, вы можете захотеть изучить использование объектов управления Sql (SMO);Вы можете использовать это, чтобы получить иерархию объектов для экземпляра Sql Server, которую вы можете затем перечислить и выбрать необходимую информацию.

Ознакомьтесь с этим набором учебных пособий, чтобы начать работу с программированием -http://www.codeproject.com/KB/database/SMO_Tutorial_1.aspx http://www.codeproject.com/KB/database/SMO_Tutorial_2.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...