簡體   English   中英

Linq Complex OrderBy by Props屬性

[英]Linq Complex OrderBy by Props attributes

我有一個類,其中一些道具標記了一些屬性。 我想在特定訂單上顯示它們。 到目前為止,我可以將它們放在一個訂單中,但不是按照我想要的順序。

這是帶有屬性的道具的簡單示例

[IncludeInEditor]
[IsInPk]
ID
[IncludeInEditor(IsReadOnlyOnModify=true)]
Name
[IncludeInEditor]
Address
[IncludeInEditor]
DOB


The order that I want is:
  1st - Props with IsInPk attribute
  2nd - Props with IncludeInEditor(IsReadOnlyOnModify=true)
  3rd - Props with IncludeInEditor

到目前為止,我沒有成功而且沒有完成100%(仍然缺少IsReadOnlyOnModify = true部分)

var properties =
item.GetType().GetProperties()
.Where(p => p.GetCustomAttributes(true)
                            .OfType<IncludeInEditorAttribute>()
                            .Count() > 0)
                .Select (x => new 
                {
                    Property = x,
                    Attribute = (IsInPkAttribute)Attribute.GetCustomAttribute(x, typeof(IsInPkAttribute), true) 
                })
                .OrderBy(x => x.Attribute != null ? 1 : -1)
                .Select(x => x.Property)
                .ToArray();

您可以創建自己的IComparer<T>實現來比較每個屬性的屬性:

public class AttributeComparer : IComparer<Attribute>
{
    public int Comparer(Attribute x, Attribute y)
    {
        if(x == null) return y == null ? 0 : -1;
        if(y == null) return 1;

        if(x is IsInPkAttribute) return (y is IsInPkAttribute) ? 0 : 1;
        else if(y is IsInPkAttribute) return -1;
        else
        {
            xa = (IncludeInEditorAttribute)x;
            ya = (IncludeInEditorAttribute)y;

            if(xa.IsReadOnlyOnModify == ya.IsReadOnlyOnModify) return 0;
            else return x.IsReadOnlyOnModify ? 1 : -1;
        }
    }
}

然后您的查詢變為:

var properties = item.GetType().GetProperties()
    .Where(p => p.GetCustomAttributes(true)
                .OfType<IncludeInEditorAttribute>()
                .Any())
    .Select (x => new 
    {
        Property = x,
        Attribute = Attribute.GetCustomAttribute(x, typeof(IsInPkAttribute), true) ?? Attribute.GetCustomAttribute(x, typeof(IncludeInEditorAttribute, true))
    })
    .OrderBy(x => x.Attribute, new AttributeComparer())
    .Select(x => x.Property)
    .ToArray();

在李的幫助下,終於有了工作。 正確的代碼是:

var properties =
                item.GetType().GetProperties()
                                .Where(p => p.GetCustomAttributes(true)
                                            .OfType<IncludeInEditorAttribute>()
                                            .Any())
                                .Select(x => new
                                {
                                    Property = x,
                                    Attribute = Attribute.GetCustomAttribute(x, typeof(IsInPkAttribute), true)
                                                    ?? Attribute.GetCustomAttribute(x, typeof(IncludeInEditorAttribute), true)
                                })
                                .OrderBy(x => x.Attribute, new IncludeInEditorAttributeComparer())
                                .Select(x => x.Property)
                                .ToArray();

李發送的這段代碼,我做了一點改動。

public class IncludeInEditorAttributeComparer : IComparer<Attribute>
    {
        public int Compare(Attribute x, Attribute y)
        {
            //In this case we can assume that
            //won´t have null values

            if (x is IsInPkAttribute && !(y is IsInPkAttribute))
                return -1;
            else if (y is IsInPkAttribute && !(x is IsInPkAttribute))
                return 1;
            else 
            { 
                bool xa = (x is IncludeInEditorAttribute ? (x as IncludeInEditorAttribute).IsReadOnlyOnModify : false);
                bool ya = (y is IncludeInEditorAttribute ? (y as IncludeInEditorAttribute).IsReadOnlyOnModify: false);

                if (xa && !ya)
                    return -1;
                else if (ya && !xa)
                    return 1;
                else
                    return 0;
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM