C# 根据另一个表中的列名从表中选择列

C# 根据另一个表中的列名从表中选择列,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,一开始我知道有类似的问题,但我的问题有点不同 我实现了一个函数,允许用户选择他想要查看的列 我创建了一个存储过程,它从UserColumns表中获取所有列名,创建一个动态sql查询,然后运行exec(@command)查询。上面描述的功能运行得很好,但是还有更多的需求我不能用这种方式处理 有TasksViewModel: public class TasksViewModel { public List<Dictionary<List<string>, List&

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

我实现了一个函数,允许用户选择他想要查看的列

我创建了一个存储过程,它从
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()
    {

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

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

假设我使用的是
List
而不是
List
<代码>任务是数据库表

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

是否有一种方法可以使用实体框架基于
UserColumns
表从
List
中选择特定列?

您可以动态创建列列表的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();
}
static Func CreateSelect(字符串[]列)
{
var parameterExpression=Expression.Parameter(typeof(Tasks),“p”);
var newExpression=Expression.New(typeof(Tasks));
var bindings=columns.Select(o=>o.Trim())
.选择(o=>
{
var pi=typeof(Tasks).GetProperty(o);
var memberExpression=Expression.Property(parameterExpression,pi);
返回表达式Bind(pi,memberExpression);
}
);
var memberInitExpression=Expression.MemberInit(newExpression,bindings);
var lambda=Expression.lambda(memberInitExpression,parameterExpression);
返回lambda.Compile();
}
并基于该lambda创建LINQ查询(columnNameList数组是UserColumns表中的行)

静态void Foo()
{
var columnNameList=新字符串[]{“ID”、“Title”、“Description”};
var tasksList=新列表
{
新任务{ID=1,Title=“T1”,FirstName=“F1”,LastName=“L1”,Description=“D1”,Date=DateTime.UtcNow},
新任务{ID=2,Title=“T2”,FirstName=“F2”,LastName=“L2”,Description=“D2”,Date=DateTime.UtcNow}
};
var tasks=tasksList.Select(CreateSelect(columnNameList)).FirstOrDefault();
}

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

您可以动态创建列列表的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();
}
static Func CreateSelect(字符串[]列)
{
var parameterExpression=Expression.Parameter(typeof(Tasks),“p”);
var newExpression=Expression.New(typeof(Tasks));
var bindings=columns.Select(o=>o.Trim())
.选择(o=>
{
var pi=typeof(Tasks).GetProperty(o);
var memberExpression=Expression.Property(parameterExpression,pi);
返回表达式Bind(pi,memberExpression);
}
);
var memberInitExpression=Expression.MemberInit(newExpression,bindings);
var lambda=Expression.lambda(memberInitExpression,parameterExpression);
返回lambda.Compile();
}
并基于该lambda创建LINQ查询(columnNameList数组是UserColumns表中的行)

静态void Foo()
{
var columnNameList=新字符串[]{“ID”、“Title”、“Description”};
var tasksList=新列表
{
新任务{ID=1,Title=“T1”,FirstName=“F1”,LastName=“L1”,Description=“D1”,Date=DateTime.UtcNow},
新任务{ID=2,Title=“T2”,FirstName=“F2”,LastName=“L2”,Description=“D2”,Date=DateTime.UtcNow}
};
var tasks=tasksList.Select(CreateSelect(columnNameList)).FirstOrDefault();
}

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

我建议您查看PIVOT SQL命令在前端为EF执行此操作,以处理您需要构建的自定义选择列表
Select(x=>newtask{Id=x.Id,Title=x.Title,Description=x.Description})
expression并将其应用于您的查询,您将得到
列表
作为所有其他列的默认值@Rafal的可能副本,这仍然是手动方式。有很多用户,而不仅仅是一个。每个用户都可以有不同的设置。我建议您查看PIVOT SQL命令在前端为EF执行此操作,以处理您需要构建的自定义选择列表
Select(x=>newtask{Id=x.Id,Title=x.Title,Description=x.Description})
expression并将其应用于您的查询,您将得到
列表
作为所有其他列的默认值@Rafal的可能副本,这仍然是手动方式。有很多用户,而不仅仅是一个。每个用户都可以有不同的设置。
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();
}