2013-02-19 25 views
5

Jak mogę zwrócić anonimowy typ, który zależy od parametru field, w którym wymieniono właściwości, które należy uwzględnić w typie anonimowym? Zadanie ma ponad 20 właściwości, a klienci chcą otrzymywać różne kombinacje właściwości.Jak zwrócić niestandardowy anonimowy typ?

public class Test 
{ 
    public class Task 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public string Description { get; set; } 
     //... more 20 properties 
    } 

    public List<Task> Tasks = new List<Task>(); 

    public Test() 
    { 
     Tasks.Add(new Task { Id = 1, Name = "Task #1", Description = "Description task #1" }); 
     Tasks.Add(new Task { Id = 2, Name = "Task #2", Description = "Description task #2" }); 
     Tasks.Add(new Task { Id = 3, Name = "Task #3", Description = "Description task #3" }); 
    } 

    public IEnumerable<object> GetAllTasks(string fields) 
    { 
     //if fields == 'Id,Name' then return anonymous type new { Id = t.Id, Name = t.Name } 
     return Tasks.Select(t => new { Id = t.Id, Name = t.Name }); 

     //if fields == 'Id,Name,Description' then return anonymous type new { Id = t.Id, name = t.Name, Description = t.Description } 
     return Tasks.Select(t => new { Id = t.Id, Name = t.Name, Description = t.Description }); 
    } 
} 
+3

anonimowych typy są znane w rodzaju kompilacji. Chcesz budować typy dynamicznie w środowisku wykonawczym. To zupełnie co innego. Oznacza to również, że konsumenci 'GetAllTasks' muszą radzić sobie z typami dynamicznymi. Poza tym nie zaleca się zwracania anonimowych typów. –

+0

Zdefiniowałeś zadanie klasy, dlaczego nie używasz go zamiast anonimowego? –

+0

Możesz użyć odbicia, aby spróbować ustawić wartość wszystkich pól przekazanych w obiekcie zadania. – glosrob

Odpowiedz

0

W takim przypadku, jeśli zadania jest IQueryable<Task> i musimy zacisnąć od źródła danych (na przykład z bazy danych) tylko te kolumny, które są niezbędne dla klienta (aby nie przeciążyć serwer DB) przydatna jest metoda SelectDynamic. W rezultacie końcowy decyzja będzie tutaj takie:

public class Test 
{ 
    public class Task 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public string Description { get; set; } 
     //... more 20 properties 
    } 

    public IQueryable<Task> Tasks; 

    public Test() 
    { 
     Tasks = new List<Task> 
      { 
       new Task {Id = 1, Name = "Task #1", Description = "Description task #1"}, 
       new Task {Id = 2, Name = "Task #2", Description = "Description task #2"}, 
       new Task {Id = 3, Name = "Task #3", Description = "Description task #3"} 
      }.AsQueryable(); 
    } 

    public IEnumerable<object> GetAllTasks(string[] fields) 
    { 
     var response = new List<object>(); 
     var customTasks = Tasks.SelectDynamic(fields).Cast<dynamic>(); 
     foreach (var t in customTasks.Take(100)) 
     { 
      dynamic expando = new ExpandoObject(); 

      if (fields.Contains("Id")) expando.Id = t.Id; 
      if (fields.Contains("Name")) expando.Name = t.Name; 
      if (fields.Contains("Description")) expando.Description = t.Description; 
      // ... other properties 

      response.Add(expando); 
     } 
     return response; 
    } 
} 

przykład użycia jest here

1

Mam nadzieję, że to pomoże Ci

public List<Task> Tasks = new List<Task>(); 

public void Test() 
{ 
    Tasks.Add(new Task { Id = 1, Name = "Task #1", Description = "Description task #1" }); 
    Tasks.Add(new Task { Id = 2, Name = "Task #2", Description = "Description task #2" }); 
    Tasks.Add(new Task { Id = 3, Name = "Task #3", Description = "Description task #3" }); 
} 

public ActionResult Index() 
{ 
    Test(); 

    return Json(GetAllTasks(), JsonRequestBehavior.AllowGet); 
} 

public IEnumerable<object> GetAllTasks() 
{ 
    return Tasks.Select(GetTask); 
} 

private object GetTask(Task task) 
{ 
    dynamic expandoObject = new ExpandoObject(); 
    //your if statment block 
    if (task.Id == 1) 
    { 
     expandoObject.Id = task.Id; 
    } 

    expandoObject.Name = task.Name; 
    expandoObject.Description = task.Description; 

    var dictionary = expandoObject as IDictionary<string, object>; 
    return dictionary.ToDictionary(item => item.Key, item => item.Value); 
} 

wynik wyświetlania:

[ 
    [ 
     { 
     "Key":"Id", 
     "Value":1 
     }, 
     { 
     "Key":"Name", 
     "Value":"Task #1" 
     }, 
     { 
     "Key":"Description", 
     "Value":"Description task #1" 
     } 
    ], 
    [ 
     { 
     "Key":"Name", 
     "Value":"Task #2" 
     }, 
     { 
     "Key":"Description", 
     "Value":"Description task #2" 
     } 
    ], 
    [ 
     { 
     "Key":"Name", 
     "Value":"Task #3" 
     }, 
     { 
     "Key":"Description", 
     "Value":"Description task #3" 
     } 
    ] 
] 
+1

Czy mógłbyś rozważyć dodanie narracji, aby wyjaśnić, dlaczego ten kod działa i co sprawia, że ​​jest to odpowiedź na pytanie? Byłoby to bardzo pomocne dla osoby zadającej pytanie i dla każdego, kto się pojawi. –

1

Możesz spróbować użyć ExpandoObject i System.Reflection:

public IEnumerable<object> GetAllTasks(string[] fields) 
{ 
    List<object> response = new List<object>(); 
    Tasks.ForEach((a) => 
    { 
     dynamic expando = new ExpandoObject(); 
     var p = expando as IDictionary<String, object>; 
     foreach (string item in fields) 
     { 
      p[item] = a.GetType().GetProperty(item).GetValue(a); 
     } 
     response.Add(expando); 
    }); 
    return response; 
} 

i próbki stosowanie jest:

static void Main(string[] args) 
{ 
    var test = new Test(); 
    var results = test.GetAllTasks(new[] { "Id"}); 
    foreach (var result in results) 
    { 
     Console.WriteLine((result as dynamic).Id); 
    } 

    results = test.GetAllTasks(new[] { "Name", "Description" }); 
    foreach (var result in results) 
    { 
     var dynamicResult=result as dynamic; 
     Console.WriteLine("{0} {1}", dynamicResult.Name, dynamicResult.Description); 
     // The following line will throw an exception 
     //Console.WriteLine((result as dynamic).Id); 
    } 
} 
Powiązane problemy