【发布时间】:2016-07-21 13:39:58
【问题描述】:
我正在寻找一种从 iQueryable 对象动态创建选择列表的方法。
具体的例子,我想做如下的事情:
public void CreateSelectList(IQueryable(of EntityModel.Core.User entities), string[] columns)
{
foreach(var columnID in columns)
{
switch(columnID)
{
case "Type":
SelectList.add(e => e.UserType);
break;
case "Name":
SelectList.add(e => e.Name);
break;
etc....
}
}
var selectResult = (from u in entities select objSelectList);
}
所以所有属性都是已知的,但是我事先不知道要选择哪些属性。这将通过 columns 参数传递。
I know i'm going to run into issues with the type of the selectResult type, because when the select list is dynamic, the compiler doesn't know what the properties of the anonymous type needs to be.
如果以上不可行:我需要它的场景如下:
我正在尝试创建一个可以实现以显示分页/过滤的数据列表的类。该数据可以是任何东西(取决于实现)。使用的 linq 是 linq 到实体。所以它们直接链接到sql数据。现在我只想选择我在列表中实际显示的实体的列。因此我希望选择是动态的。我的实体可能有一百个属性,但如果列表中只显示其中的 3 个,我不想生成一个查询,选择所有 100 列的数据,然后只使用其中的 3 个。如果有我没有想到的不同方法,我愿意接受想法
编辑:
关于约束的一些说明:
- 查询需要使用 linq 到实体(请参阅问题主题)
- 一个实体可能包含 100 列,因此选择所有列然后只读取我需要的列不是一个选项。
- 最终用户决定显示哪些列,因此要选择的列在运行时确定
- 我需要创建一个 SINGLE select,有多个 select 语句意味着对数据库有多个查询,这是我不想要的
【问题讨论】:
-
我一直在网上搜索,发现一些人有类似的问题。但是,建议的解决方案使用字符串和 propertyinfo 对象来确定创建选择表达式的成员。我的目标是能够在没有字符串属性查找的情况下获得类型安全的解决方案。就像我在原始帖子中所说的那样,所有属性都是已知的。理想情况下,我想使用 lambda 将表达式指向要选择的属性。
-
如果你不想使用字符串,你可以使用 PropertyInfo 代替,这是类型安全的。此外,即使您确实使用了字符串,Expression.Property 通过检查属性是否真的存在于声明的类型上并在您的属性名称无效时抛出异常来使其“安全”。
-
首先,最好提供您正在寻找的方法的签名。其次,不幸的是,LINQ to Entities 不允许投影到实体类型,那么您打算如何处理呢?
-
@TimCopenhaver,您认为所有数据都来自同一个表的假设是错误的。大多数情况下,数据来自查询大量表的视图,并不意味着要选择所有列。但是,是的,我们进行了测试并选择了所有列使我们的 sql 服务器非常热
-
@PaulVrugt
select new User { UserType = u.UserType, Name = u.Name }是有效的 LINQ,select u.UserType, u.Name不是。无论如何,我只想弄清楚是否可以帮助您。创建动态选择没有问题(如果您在表达式区域中查看我的答案,您可以看到),问题是选择目标对象 type 和 EF 限制。如果您可以创建一个具有所有这些属性的类,但 EF 不将其识别为实体(也称为 DTO 对象),那么它是可行的。另一种选择是 DynamicLINQ,它在运行时为投影创建动态类。
标签: c# entity-framework linq linq-to-entities