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  Log.ProcessName == CustomReport.ProcessName); foreach (Pair filter in CustomReport.ExtColsToFilter) { sExtFilters = "" + filter.First + "" + filter.Second + ""; query = query.Where(Log => Log.FormattedMessage.Contains(sExtFilters)); } 

简短的回答是

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

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

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


一些评论迫使我认真考虑我是否正确,我的意思是动态输出列表实际上是可能的 ,并且我得出结论,尽管这是一个危险的游泳 – 反对当前的想法。 为了完成这个特技,你必须:

  1. 使用Reflection.Emit生成新类型。
  2. 生成一个表达式树,使用Expression.MemberInit对其进行初始化。
  3. 编译表达式并将其传递给Select方法。
  4. 从您的方法返回一个弱类型的System.Object ,并使用Reflection按名称访问成员。

这不是我想要在生产代码中看到的那种东西,但是你有它 – 它是可能的。

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