LINQ To SQL动态选择

时间:2010-06-07 14:05:15

标签: c# asp.net linq-to-sql

有人可以告诉我如何在LINQ To SQL语句中指示我希望在运行时返回哪些列吗?

我允许用户在复选框列表中选择项目,这些项目表示他们希望在绑定到L2S查询结果的网格视图中显示的列。

我能够动态生成WHERE子句但是无法对SELECT片段执行相同的操作。这是一个示例:

var query = from log in context.Logs select log;
                query = query.Where(Log => Log.Timestamp > CustomReport.ReportDateStart);
                query = query.Where(Log => Log.Timestamp < CustomReport.ReportDateEnd);
                query = query.Where(Log => Log.ProcessName == CustomReport.ProcessName);

                foreach (Pair filter in CustomReport.ExtColsToFilter)
                {
                    sExtFilters = "<key>" + filter.First + "</key><value>" + filter.Second + "</value>";
                    query = query.Where(Log => Log.FormattedMessage.Contains(sExtFilters));
                }

2 个答案:

答案 0 :(得分:3)

简短的回答是

方法必须具有已知的特定返回类型。那个类型可以是System.Object,但是你必须使用很多丑陋的反射代码才能真正获得成员。在这种情况下,您还必须使用大量丑陋的 reflection 表达式树代码来生成返回值。

如果您尝试在UI端动态生成列 - 请停止这样做。在设计时定义列,然后只显示/隐藏您实际需要/希望用户看到的列。让您的查询返回可能可见的所有列。

除非您注意到选择所有数据列的严重性能问题(在这种情况下,您可能在数据库级别上存在非覆盖索引问题),否则使用此方法会更好。生成谓词和动态排序是完全没问题的,但你真的不想用输出列表做这个。


有些评论迫使我认真考虑一下,我的动机输出列表实际上是否可能是否正确,我得出的结论是,尽管是危险的游泳 - 反对当前的想法。为了摆脱这种噱头,你必须:

  1. 使用Reflection.Emit生成新类型。
  2. 生成一个表达式树,使用Expression.MemberInit初始化它。
  3. 编译表达式并将其传递给Select方法。
  4. 从您的方法中返回弱类型的System.Object,并使用Reflection按名称访问成员。
  5. 这不是我想要在生产代码中看到的那种东西,但是你有它 - 它是可能的。

答案 1 :(得分:1)

您不需要在查询级别执行此操作(无论如何,这将非常困难,因为您需要在运行时动态创建类型)...在GridView本身中处理它更容易,明确声明要显示的列。

相关问题