首页 > 解决方案 > 根据另一个表中的列名从表中选择列

问题描述

一开始我知道有类似的问题,但我的有点不同。

我实现了一个功能,允许用户选择他想查看的列。

我创建了一个存储过程,它从UserColumns表中获取所有列名,创建一个动态 sql 查询,然后运行该exec (@command)查询。上面描述的功能非常好用,但是有更多的需求我不能用这种方式处理。

TasksViewModel

public class TasksViewModel
{
    public List<Dictionary<List<string>, List<List<object>>>> Tasks { get; set; }

    public List<UserDefaultStatusesViewModel> UserStatuses { get; set; }

    public List<ZgloszenieStatus> TaskStatuses { get; set; }

    public TasksViewModel()
    {

    }
}

TasksSELECT x,y,z... FROM table...由运行查询的存储过程填充。

我正在使用这种方法:

private static IEnumerable<Dictionary<List<string>, List<List<object>>>> Read(DbDataReader reader)
    {
        var dict = new Dictionary<List<string>, List<List<object>>>();

        var cols = new List<string>();

        for (int temp = 0; temp < reader.FieldCount; temp++)
        {
            cols.Add(reader.GetName(temp));
        }

        var items = new List<List<object>>();

        while (reader.Read())
        {
            var tmp = new List<object>();

            for (int i = 0; i < reader.FieldCount; i++)
            {
                tmp.Add(reader.GetValue(i));
            }

            items.Add(tmp);

        }

        dict.Add(cols, items);

        foreach (var item in dict)
        {

        }

        yield return dict;
    }

我发现这非常复杂,但目前我不知道是否有另一种方法可以做到这一点。

我在我的应用程序中使用实体框架。

想象一下,我正在使用List<Tasks>而不是List<Dictionary<List<string>, List<List<object>>>>. Tasks是数据库表。

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

    public string Title { get; set; }

    public string Description { get; set; }

    public DateTime Date { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

用户只想查看ID,Title,Description列,因此UserColumns表格如下所示:

UserId | ColumnName
  1    |      ID
  2    |    Title
  3    |    Description

有没有办法使用实体框架List<Tasks>根据表选择特定列?UserColumns

标签: c#sql-serverentity-framework

解决方案


您可以为列列表动态创建 lambda

static Func<Tasks, Tasks> CreateSelect(string[] columns)
{
    var parameterExpression = Expression.Parameter(typeof(Tasks), "p");
    var newExpression = Expression.New(typeof(Tasks));

    var bindings = columns.Select(o => o.Trim())
        .Select(o =>
        {
            var pi = typeof(Tasks).GetProperty(o);
            var memberExpression = Expression.Property(parameterExpression, pi);
            return Expression.Bind(pi, memberExpression);
        }
    );
    var memberInitExpression = Expression.MemberInit(newExpression, bindings);
    var lambda = Expression.Lambda<Func<Tasks, Tasks>>(memberInitExpression, parameterExpression);
    return lambda.Compile();
}

并基于该 lambda 创建一个 LINQ 查询(columnNameList 数组是来自 UserColumns 表的行)

static void Foo()
{
    var columnNameList = new string[] { "ID", "Title", "Description" };
    var tasksList = new List<Tasks>
    {
        new Tasks{ ID=1, Title="T1", FirstName="F1", LastName="L1", Description="D1", Date=DateTime.UtcNow },
        new Tasks{ ID=2, Title="T2", FirstName="F2", LastName="L2", Description="D2", Date=DateTime.UtcNow }
    };

    var tasks = tasksList.Select(CreateSelect(columnNameList)).FirstOrDefault();
}

我希望这能回答你的问题。


推荐阅读