Только значения поля коллекции дескриптора свойства Entity Framework

.. Привет, я пытаюсь объединить некоторые значения столбца из любого объекта, как это:

var valor = "";

        PropertyDescriptorCollection objProperties = TypeDescriptor.GetProperties(obj);


        foreach (PropertyDescriptor objProperty in objProperties)
        {

            if (objProperty.Name != "AuditoriaUC" && objProperty.Name != "AuditoriaFC"
                && objProperty.Name != "AuditoriaIPC" && objProperty.Name != "AuditoriaUM"
                && objProperty.Name != "AuditoriaFM" && objProperty.Name != "AuditoriaIPM"
                && objProperty.Name != "AuditoriaEliminado")
            {
                valor = valor + " " + objProperty.Name + ": " + Convert.ToString(objProperty.GetValue(obj));
            }
        }

        return valor;

Тем не менее, он также показывает мне ссылки на столбцы. Другими словами, это также печатает это в конце:

"ArchivosAdjuntos:System.Data.Objects.DataClasses.EntityCollection`1[XXX.MyProject.Model.Entities.ArchivosAdjuntos] 
 CorrelativoActualPorPeriodo: XXX.MyProject.Model.Entities.CorrelativoActualPorPeriodo
 CorrelativoActualPorPeriodoReference: System.Data.Objects.DataClasses.EntityReference`1[XXX.MyProject.Model.Entities.CorrelativoActualPorPeriodo] 
 EntityState: Modified 
 EntityKey: System.Data.EntityKey"

Я хотел бы только вернуть значения столбца, чего можно добиться, просто сравнив значение последнего столбца с жестко закодированной строкой, чтобы разорвать foreach. Но я бы очень хотел узнать, есть ли лучший способ.

1 ответ

Решение

Сначала вы можете использовать метод GetProperties класса Type, который позволяет выполнять некоторую фильтрацию, например, возвращать только открытые свойства:

PropertyInfo[] props = obj.GetType().GetProperties(BindingFlags.Public 
                                                   | BindingFlags.Instance);

Затем вы можете использовать LINQ для фильтрации свойств ссылочного типа. Например, вы можете удалить все свойства ссылочного типа (кроме строк) и выполнить итерации по ним:

var valueProps = props.Where(p => !p.PropertyType.IsClass 
                                || p.PropertyType == typeof(string))
valueProps.ToList().ForEach(p => 
                           valor += p.Name + ": " 
                                 + (p.GetValue(obj) ?? "null"));

Наконец, для тех свойств, которые вы исключаете, используя жестко закодированный список, вы можете добавить этот жестко закодированный список имен свойств в приведенное выше выражение фильтрации. Однако вы можете также рассмотреть возможность добавления атрибута в поля, которые вы хотите исключить, и удалить любое свойство, включая этот атрибут, из списка свойств. Это было бы атрибутом

[AttributeUsage(AttributeTargets.Property)]
public class ExcludeThisPropertyAttribute: Attribute
{
}

Вы можете установить это на вас классы, такие как

public class YourClass
{
    public string PropertyThatIsIncluded { get; set; }
    public int ThisIsIncludedToo { get; set; }
    //more value type properties to be included ...

    [ExcludeThisProperty]
    public string AuditoriaUC { get; set; }
    [ExcludeThisProperty]
    public string AuditoriaFC { get; set; }
    //more value type properties explicitly excluded ...

    //reference type properties like this one will be automatically excluded
    public CorrelativoActualPorPeriodo CorrelativoActualPorPeriodo { get; set; }
}

Затем выражение для извлечения атрибутов типа значения будет обновлено, чтобы исключить те, которые содержат атрибут:

var valueProps = props.Where(p => 
               p.GetCustomAttributes(typeof(ExcludeThisPropertyAttribute), true) == 0
               &&(!p.PropertyType.IsClass 
                    || p.PropertyType == typeof(string)))    

В вашем случае кажется, что вы используете Entity Framework, поэтому, если ваши классы были сгенерированы EF, чтобы иметь возможность устанавливать атрибуты для свойств, вам нужно будет придерживаться подхода, подобного использованию вспомогательного класса метаданных.

Другие вопросы по тегам