After playing around with LINQ-to-SQL today I noticed that the generated DataContext subclass exposes a Log property of type TextWriter.
I initially replaced this with a StringWriter backed by a local StringBuilder variable so I could read the output, but then decided to take advantage of the fact that the generated class is a partial class:
//Generated class: WidgetDb.designer.cs
public partial class WidgetDbDataContext : System.Data.Linq.DataContext {
...
}
//My partial implementation: WidgetDbDataContext.cs
public partial class WidgetDbDataContext {
private StringBuilder logBuilder = new StringBuilder();
public String GetLoggedInformation() {
return logBuilder.ToString();
}
partial void OnCreated() {
Log = new StringWriter(logBuilder);
}
}
I could then perform a sample query or two in my ASPX:
private void doLinqStuff() {
WidgetDbDataContext db = new WidgetDbDataContext();
var widgets = from w in db.Widgets select w;
WidgetGrid.DataSource = widgets;
WidgetGrid.DataBind();
WidgetCount.Text = widgets.Count().ToString();
StatusLog.Text += db.GetLoggedInformation().Replace("\n", "<br/>");
}
The output of StatusLog.Text from this was:
SELECT [t0].[WidgetId], [t0].[WidgetName], [t0].[WidgetDescription], [t0].[WidgetPrice], [t0].[IsActive] FROM [dbo].[Widgets] AS [t0] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1 SELECT COUNT(*) AS [value] FROM [dbo].[Widgets] AS [t0] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1
This is potentially helpful for learning how your expressions translate to SQL, but you probably wouldn’t want to do this in production :)
I then decided to search Google for “DataContext.Log” and found out that people far smarter than me have already come up with better solutions. Ah well, at least I learnt about extending the generated DataContext, as well as some smart ways of logging from others. :)