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

まず、TypeクラスのGetPropertiesメソッドを使用できます。これにより、パブリックプロパティのみを返すなどのフィルタリングが可能になります。

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

あなたの場合、エンティティフレームワークを使用しているようです。したがって、クラスがEFによって生成されている場合、プロパティに属性を設定できるようにするには、補助メタデータクラスを使用するなどのアプローチに従う必要があります。

于 2012-12-06T19:29:58.003 に答える