如何返回自定义匿名类型?

And*_*lev 5 c# linq dynamic anonymous-types asp.net-web-api

如何返回依赖于fields参数的匿名类型,其中列出了必须包含在匿名类型中的属性?任务实体具有20多个属性,并且客户希望接收不同的属性组合.

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 });
    }
}
Run Code Online (Sandbox Code Playgroud)

And*_*lev 0

在这种情况下,如果任务是IQueryable<Task>并且我们需要从数据源(例如,从数据库)仅收紧客户端所需的那些列(不要使数据库服务器过载),则有一个SelectDynamic方法很有用。因此,最终的决定将如下:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

示例用法在这里