Skip to content

Instantly share code, notes, and snippets.

@joeriks
Last active May 22, 2018 21:08
Show Gist options
  • Select an option

  • Save joeriks/137d6280226db105d71c to your computer and use it in GitHub Desktop.

Select an option

Save joeriks/137d6280226db105d71c to your computer and use it in GitHub Desktop.
Linqpad Extension method to generate csv with class (keep strongly typed) (Temp Tables in LinqPad)

##Preparation:

  1. Get Nuget CsvHelper

  2. Copy extension method to My Extensions in LinqPad

##Usage:

  1. Write your query (C# Statements)

Company.Take(100).DumpAsClassAndCsv("Company", "100 first companies");

  1. The extension saves a csv with the actual data + a linqpad C# code file into a subfolder in your Linqpad My Queries folder. The code file has a class definition + code to read the data from the csv into a strongly typed list (i.e. IEnumerable).

  2. Open the generated linqpad file from the My Queries window and run it as is, or combine it with more queries.

// 100 first companies
// Generated 2014-08-19 13:48:40
void Main() {
var companiesallEnumerable=GetCompanyRecords(@"C:\linqpad\my queries\company\100 first companies.csv");
companiesallEnumerable.Dump();
}
public IEnumerable<Company> GetCompanyRecords(string filePath){
var csvReader = new CsvHelper.CsvReader(File.OpenText(fileName));
return csvReader.GetRecords<Company>();
}
public class Company {
public Int32 Id {get;set;}
public String Name {get;set;}
public DateTime? RegDate {get;set;}
public String Type {get;set;}
}
public static class MyExtensions
{
// Write custom extension methods here. They will be available to all queries.
public static string CodeGen(this Type type, string typeName, string description, string filePath){
var t = new StringBuilder();
var className = type.Name.StartsWith("<>")?"AnonymousType":type.Name;
if (typeName!="") className = typeName;
var listName = className.ToLower() + "Enumerable";
if (description!="")
t.AppendLine("// " + description);
t.AppendLine("// Generated " + DateTime.Now.ToString());
t.AppendLine("void Main() {");
t.AppendLine(" var " + listName + @"=Get" + typeName + @"Records(@""" + filePath + @""");");
t.AppendLine(" " + listName + ".Dump();");
t.AppendLine("}");
t.AppendLine(@"public IEnumerable<" + className + "> Get" + typeName + "Records(string filePath){");
t.AppendLine(@" var csvReader = new CsvHelper.CsvReader(File.OpenText(filePath));");
t.AppendLine(@" return csvReader.GetRecords<" + className + @">();");
t.AppendLine("}");
t.AppendLine("public class " + className + " {");
type.GetFields().Select (x => new {Name=x.Name, Type=(x.FieldType.IsGenericType && x.FieldType.GetGenericTypeDefinition()==typeof(Nullable<>))?Nullable.GetUnderlyingType(x.FieldType).Name + "?":x.FieldType.Name}).ToList().ForEach(row=>{
t.AppendLine(" public " + row.Type + " " + row.Name + " {get;set;}");
});
type.GetProperties().Select(x=>new { Name = x.Name, Type = x.PropertyType.Name}).ToList().ForEach(row=>{
t.AppendLine(" public " + row.Type + " " + row.Name + " {get;set;}");
});
t.AppendLine("}");
return t.ToString();
}
public static void DumpAsClassAndCsv<TIn>(this IEnumerable<TIn> records, string typeName, string queryDescription){
var path = Path.GetDirectoryName(Util.CurrentQueryPath);
if (path !=null) {
path = path + "/" + typeName;
Directory.CreateDirectory(path);
var csvPath = path + "/" + queryDescription + ".csv";
Util.WriteCsv(records, csvPath);
var code = CodeGen(records.First().GetType(), typeName, queryDescription, csvPath);
var sb = new StringBuilder();
sb.AppendLine(@"<Query Kind=""Program"">");
sb.AppendLine(@"<NuGetReference>CsvHelper</NuGetReference>");
sb.AppendLine(@"</Query>");
sb.AppendLine(code);
var codeFilePath = path + "/" + queryDescription + ".linq";
File.WriteAllText(codeFilePath,sb.ToString());
Console.WriteLine("Generated file " + codeFilePath);
} else {
throw new Exception("Save current query first");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment