c# - 根据另一个表中的列名从表中选择列
问题描述
一开始我知道有类似的问题,但我的有点不同。
我实现了一个功能,允许用户选择他想查看的列。
我创建了一个存储过程,它从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()
{
}
}
Tasks
SELECT 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
解决方案
您可以为列列表动态创建 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();
}
我希望这能回答你的问题。
推荐阅读
- python - 气流:超时后如何将 ExternalTaskSensor 运算符标记为成功
- matplotlib - 如何更改图例标签的 alpha?
- codenameone - 禁用后启用标签滑动(在代号一上)
- javascript - 在 ngFor 循环中使用 Object.keys 时如何设置默认值?
- colors - 使用 Imagemagick 将图像处理为“默认调色板”(例如 16 或 256 色)
- .net - 1.5 小时后 Azure 登录请求超时
- java - 如何使用 google-docs-api 和 Java 在新文档中设置页眉和页脚
- fortran - openmpi 和 gfortran 错误:没有通用“mpi_waitall”的特定子程序
- mysql - 选择用户没有任何其他活动订阅的所有订阅
- android - Android Management API 的委派范围似乎没有被 Companion 应用程序获取