Выберите только участников с анонимным именем - PullRequest
0 голосов
/ 16 декабря 2018

У меня есть класс с именем Employee (это только его часть):

public class Employee
{        
    public int ID { get; set; }

    public string Place { get; set; }

    [IncludeinReport]
    public string BusinessVertical { get; set; }

    [IncludeinReport]
    public string Region { get; set; }

    public string Country { get; set; }

    [IncludeinReport]
    public string BusinessUnit { get; set; }
}

Я хочу использовать Linq для выбора только тех свойств, которые имеют атрибут IncludeinReport.Ниже приведено описание linq, все, что я делаю, это просто , вручную выбирая свойства с атрибутом:

                 var report = from c in Employee                
                 orderby c.Region, c.BusinessUnit
                 select new
                 {
                     c.BusinessVertical,
                     c.Region,
                     c.BusinessUnit,
                 }

Но я хочу иметь возможность сделать что-то вроде этого:

                 var report = from c in Employee                
                 orderby c.Region, c.BusinessUnit
                 select c.members.hasattribute(IncludeinReport)

1 Ответ

0 голосов
/ 16 декабря 2018

Не уверен, что это лучший способ, но вы можете сделать следующее.

Объект

public class Employee
{        
    public int ID { get; set; }

    public string Place { get; set; }

    [IncludeinReport]
    public string BusinessVertical { get; set; }

    [IncludeinReport]
    public string Region { get; set; }

    public string Country { get; set; }

    [IncludeinReport]
    public string BusinessUnit { get; set; }
}

public class IncludeinReport:Attribute
{
}

Пример данных

var list = new List<Employee>
    {
        new Employee{ID = 1, Region = "Europe", BusinessUnit="Software", BusinessVertical = "Sample1"},
        new Employee{ID = 1, Region = "Asia", BusinessUnit="Software", BusinessVertical = "Sample1"},
        new Employee{ID = 1, Region = "Asia", BusinessUnit="Hardware", BusinessVertical = "Sample1"},
        new Employee{ID = 1, Region = "Europe", BusinessUnit="Software", BusinessVertical = "Sample1"},
        new Employee{ID = 1, Region = "Asia", BusinessUnit="Telecom", BusinessVertical = "Sample1"},
        new Employee{ID = 1, Region = "Europe", BusinessUnit="Software", BusinessVertical = "Sample1"},
    };

Для выше,Вы можете запросить следующим образом.Вам нужно выбрать свойства, которые имеют обязательный атрибут.Этот список свойств используется в вашем запросе к данным.И, наконец, вы используете ExpandoObject для создания требуемого типа.

var properties =  typeof(Employee).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(IncludeinReport))).Select(v=>v);
var intermediate = list.OrderBy(c => c.Region).ThenBy(x=>x.BusinessUnit).SelectMany((x,index)=> properties.Select(v=> new {GroupId = index, Dict = new KeyValuePair<string,object>(v.Name, v.GetValue(x))})) ;
var resultList = new List<ExpandoObject>();

 foreach(var item in intermediate.GroupBy(x=>x.GroupId))
 {
    resultList.Add(CreateObject(item.ToList().Select(x=>x.Dict)));
 }

Где CreateObject определен как

ExpandoObject CreateObject(IEnumerable<KeyValuePair<string,object>> kvps)
{
    dynamic returnValue = new ExpandoObject();
    var dict = returnValue as IDictionary<string, object>;
    foreach (var kvp in kvps)
    {
        dict.Add(kvp.Key, kvp.Value);
    }
    return returnValue;
}

Выход

enter image description here

Обновление

Вы можете использовать метод Extension для CreateObject, который сделает его битовым для чтения.

public static class Extensions
{
    public static ExpandoObject CreateObject(this IEnumerable<KeyValuePair<string,object>> source)
    {
        dynamic returnValue = new ExpandoObject();
        var dict = returnValue as IDictionary<string, object>;
        foreach (var kvp in source)
        {
            dict.Add(kvp.Key, kvp.Value);
        }
        return returnValue;
    }
}

После чего запрос становится.

var properties =  typeof(Employee).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(IncludeinReport))).Select(v=>v);
var intermediate = list.OrderBy(c => c.Region).ThenBy(x=>x.BusinessUnit).SelectMany((x,index)=> properties.Select(v=> new {GroupId = index, Dict = new KeyValuePair<string,object>(v.Name, v.GetValue(x))})) ;
var resultList = intermediate.GroupBy(x=>x.GroupId).Select(x=>x.ToList().Select(c=>c.Dict).CreateObject());
...