Как получить все имена свойств в сущности? - PullRequest
9 голосов
/ 02 мая 2011


Я пытаюсь передать объект сущности методу и вернуть все имена свойств в нем.
Я использую этот код, чтобы получить все имена реквизита:

return classObject.GetType().GetProperties();

Проблема в том, что этот код возвращает "EntityKey" и "EntityState" в качестве свойств, когда я использую его с Entity Object.
Есть ли способ сделать это?

Спасибо заранее

Ответы [ 4 ]

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

Требуются все прямые свойства, но не свойства базового типа, который в вашем случае равен EntityObject:

var type = classObject.GetType();
//alternatively call out directly: typeof(EntityObject).GetProperties()...
var basePropertyNames = type.BaseType.GetProperties().Select(x => x.Name);
var props = type.GetProperties().Where(p => !basePropertyNames.Contains(p.Name));

В этом примере предполагается, что существует базовый тип (которыйсначала дело с БД), рефакторинг, когда это не гарантируется.

Редактировать из комментария @ Matt: все вышеперечисленное излишне, может дать мне пощечину, если я не буду думать об этом - просто используйте правильные флаги привязки:

return classObject.GetType().GetProperties(BindingFlags.DeclaredOnly | 
                                           BindingFlags.Public | 
                                           BindingFlags.Instance);
8 голосов
/ 02 мая 2011

Это также возможно без размышлений:

using (var context = new ModelContainer())
{
    // Access CSDL
    var container = context.MetadataWorkspace
                           .GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);
    // Access name of related set exposed on your context
    var set = container.BaseEntitySets[context.YourEntitySet.EntitySet.Name];
    // Access all properties
    var properties = set.ElementType.Members.Select(m => m.Name).ToList();
    // Access only keys
    var keys = set.ElementType.KeyMembers.Select(m => m.Name).ToList();
}

Как видите, у вас есть доступ к гораздо большему, чем имена.Пример показывает, что теперь вы можете узнать, какое свойство является частью ключа.Если вы обращаетесь к Members напрямую, вы можете узнать, какое свойство является скалярным, сложным типом или свойством навигации.

Вся информация уже загружена, поэтому нет необходимости размышлять.Если вы хотите использовать отражение, не забудьте использовать его только один раз (в первый раз, когда вам это нужно), а затем сохраните и повторно используйте полученные имена свойств.Отражение медленное, поэтому использовать его каждый раз, когда вам нужны имена, - плохая практика.

2 голосов
/ 02 мая 2011

У меня была такая же проблема.Решение, которое я нашел, состояло в том, чтобы создать массив с именем возвращаемых свойств (мне просто нужно несколько).В вашем случае, так как отслеживать все свойства может быть трудоемко, я бы отфильтровал свойства EntityKey и EntityState и вернул бы все остальные.Код будет выглядеть примерно так:

public IEnumerable<PropertyInfo> GetProperties()
{
    Type t = this.GetType();

    return t.GetProperties()
        .Where(p => (p.Name != "EntityKey" && p.Name != "EntityState"))
        .Select(p => p).ToList();
}

Не знаю, есть ли лучшее решение, но было бы неплохо;) Надеюсь, это поможет!

1 голос
/ 02 мая 2011

Как заявлено BrokenGlass, но будьте осторожны, если вам нужна производительность, и вы хотите сделать это в циклах.Отражение не является быстрым делом.

Если вам нужна производительность, вы можете захотеть поместить виртуальный метод в ваш базовый класс для извлечения свойств в виде массива строк или чего-либо еще и переопределить его во всех производных классах.Это был бы быстрый подход, но с большим количеством кодирования.

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