0

..嗨,我正在尝试连接来自任何实体的一些列值,如下所示:

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 来实现。但我真的很想知道是否有更好的方法。

4

1 回答 1

0

First you could use the GetProperties method of the Type class, which allows some filtering like returning only public properties:

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

Then you could use LINQ for filtering the reference type properties.For example you could remove all reference type properties (except strings) and iterate over them:

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

Finally, for those properties that you are excluding using a hardcoded list, you could add that hardcoded list of property names into the filtering expression above. However you could also consider adding an attribute on the fields that you want to exclude and remove any property including that attribute from the properties list. This would be the attribute

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

You could set it on you classes like

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

Then the expression to extract the value type attributes would be updated to exclude those that contain the attribute:

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

In your case it seems you are using entity framework, so if your classes have been generated by EF, in order to be able to set attributes on properties you would need to follow an approach like using an auxiliary metadata class

于 2012-12-06T19:29:58.003 回答