LINQPad CSV driver.
$ dotnet add package CsvLINQPadDriverCsvLINQPadDriver is the LINQPad data context dynamic driver for querying CSV files.
string, no data type detection is provided.Latest CsvLINQPadDriver.*.lpx6/CsvLINQPadDriver.*.lpx for LINQPad manual installation.
Let's have 2 CSV files:
Authors.csv
Id,Name
1,Author 1
2,Author 2
3,Author 3
Books.csv
Id,Title,AuthorId
11,Author 1 Book 1,1
12,Author 1 Book 2,1
21,Author 2 Book 1,2
CsvLINQPadDriver will generate data context similar to (simplified) if relations detection is enabled:
public class CsvDataContext
{
public CsvTableBase<RAuthor> Authors { get; private set; }
public CsvTableBase<RBook> Books { get; private set; }
}
// record/class for LINQPad, class for LINQPad 5.
public sealed record RAuthor
{
public string? Id { get; set; }
public string? Name { get; set; }
public IEnumerable<RBook>? Books { get; set; }
}
public sealed record RBook
{
public string? Id { get; set; }
public string? Title { get; set; }
public string? AuthorId { get; set; }
public IEnumerable<RAuthor>? Authors { get; set; }
}
And you can query data with LINQ like:
from book in Books
join author in Authors on book.AuthorId equals author.Id
select new { author.Name, book.Title }
Add connection link.View more drivers...Show all drivers and type CsvLINQPadDriverGet latest CsvLINQPadDriver.*.lpx6 file.
Add connection link.View more drivers...Install driver from .LPX6 file... and select downloaded lpx6 file.Get latest CsvLINQPadDriver.*.lpx file.
Add connection link.View more drivers...Browse... and select downloaded lpx file.CSV files connection can be added to LINQPad the same way as any other connection.
Add connectionCSV Context Driver and click NextCtrl adds files) from Explorer. Optionally configure other options.Ctrl adds files, Alt toggles * and ** masks). Wildcards ? and * are supported; **.csv searches in folder and its sub-folders.
c:\Books\Books?.csv: Books.csv, Books1.csv, etc. files in folder c:\Booksc:\Books\*.csv: all *.csv files in folder c:\Booksc:\Books\**.csv: all *.csv files in folder c:\Books and its sub-folders.UTF-8 is used by default.[!NOTE] Driver does not track files changes.
,, \t, etc. Auto-detected if empty.Separator or NewLine character, it is wrapped in Quote characters. If quoted field contains a Quote character, it is preceded by Escape character.Separator, NewLine or Escape character, it should be preceded by Escape character.Separator, Quote or NewLine characters as they cannot be escaped." if empty." if empty.# (which is used by default) will be ignored.Ordinal is used by default.Equals and GetHashCode methods.Dump(): LINQPad will not show relations content when Dump()ed. This prevents loading too many data.There is no definition of relations between CSV files, but we can guess some relations from files and columns names.
Relations between fileName.columnName are detected in cases similar to following examples:
Books.AuthorId <-> Authors.Id
Books.AuthorsId <-> Authors.Id
Books.AuthorId <-> Authors.AuthorId
Books.Id <-> Authors.BookId
When executing LINQ query for CSV connection:
Don't expect performance comparable with SQL server. But for reasonably sized CSV files there should not be any problem.
Everything is string. Because there is no data type info in CSV files, this is the best we can do - see conversion extension methods.
Generated data object is sealed mutable class or record (LINQPad 6+). You can create record's shallow copy using with expression.
string? ToString();
bool Equals(T? obj);
bool Equals(object? obj);
static bool operator == (T? obj1, T? obj2);
static bool operator != (T? obj1, T? obj2);
int GetHashCode();
string? this[int index] { get; set; }
string? this[string index] { get; set; }
string? ToString();
Formats object the way PowerShell Format-List does.
[!NOTE] Relations are not participated.
int GetHashCode();
Returns object hash code.
[!IMPORTANT]
- Generated data object is mutable.
- Hash code is not cached and recalculated each time method is called.
- Each time driver is reloaded string hash codes will be different.
[!NOTE] Depends on string comparison driver setting. Relations are not participated.
bool Equals(T? obj);
bool Equals(object? obj);
[!NOTE] Depends on string comparison driver setting. Relations are not participated.
static bool operator == (T? obj1, T? obj2);
static bool operator != (T? obj1, T? obj2);
[!NOTE] Depends on string comparison driver setting. Relations are not participated.
string? this[int index] { get; set; }
string? this[string index] { get; set; }
See properties access below.
[!NOTE] Relations are not participated.
IndexOutOfRangeException will be thrown.var author = Authors.First();
// Property (preferable).
var name = author.Name;
author.Name = name;
// Integer indexer.
var name = author[0];
author[0] = name;
// String indexer.
var name = author["Name"];
author["Name"] = name;
Property index can be found by hovering over property name at the connection pane or by using code below:
Authors.First()
.GetType().GetProperties()
.Where(p => !p.GetCustomAttributes().Any())
.Select((p, i) => new { Index = i, p.Name })
string (and ReadOnlySpan<char> for .NET Core/.NET) to T?CultureInfo.InvariantCulture is used for provider by default.null is returned for null or empty input.CsvLINQPadDriver.ConvertException is thrown for non-Safe methods.public static class Styles
{
public const NumberStyles Integer =
NumberStyles.Integer |
NumberStyles.AllowThousands;
public const NumberStyles Float =
NumberStyles.Float |
NumberStyles.AllowThousands;
public const NumberStyles Decimal =
NumberStyles.Number;
public const DateTimeStyles DateTimeOffset =
DateTimeStyles.None;
public const DateTimeStyles DateTime =
DateTimeStyles.None;
public const DateTimeStyles UtcDateTime =
DateTimeStyles.AdjustToUniversal |
DateTimeStyles.AssumeUniversal;
public const TimeSpanStyles TimeSpan =
TimeSpanStyles.None;
// .NET 6+
public const DateTimeStyles DateOnly =
DateTimeStyles.None;
// .NET 6+
public const DateTimeStyles TimeOnly =
DateTimeStyles.None;
}
// Bool
bool? ToBool(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
bool? ToBoolSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// SByte
sbyte? ToSByte(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
sbyte? ToSByteSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// Byte
byte? ToByte(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
byte? ToByteSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// Short
short? ToShort(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
short? ToShortSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// UShort
ushort? ToUShort(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
ushort? ToUShortSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// Int
int? ToInt(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
int? ToIntSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// UInt
uint? ToUInt(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
uint? ToUIntSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// Long
long? ToLong(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
long? ToLongSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// ULong
ulong? ToULong(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
ulong? ToULongSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// NInt: .NET 5+
nint? ToNInt(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
nint? ToNIntSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// NUInt: .NET 5+
nuint? ToNUInt(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
nuint? ToNUIntSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// BigInteger
BigInteger? ToBigInteger(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
BigInteger? ToBigIntegerSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// Float
float? ToFloat(
NumberStyles style = Styles.Float,
IFormatProvider? provider = null);
float? ToFloatSafe(
NumberStyles style = Styles.Float,
IFormatProvider? provider = null);
// Double
double? ToDouble(
NumberStyles style = Styles.Float,
IFormatProvider? provider = null);
double? ToDoubleSafe(
NumberStyles style = Styles.Float,
IFormatProvider? provider = null);
// Decimal
decimal? ToDecimal(
NumberStyles style = Styles.Decimal,
IFormatProvider? provider = null);
decimal? ToDecimalSafe(
NumberStyles style = Styles.Decimal,
IFormatProvider? provider = null);
// Half: .NET 5+
Half? ToHalf(
NumberStyles style = Styles.Float,
IFormatProvider? provider = null);
Half? ToHalfSafe(
NumberStyles style = Styles.Float,
IFormatProvider? provider = null);
// Int128: .NET 7+
static Int128? ToInt128(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
static Int128? ToInt128Safe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// UInt128: .NET 7+
static UInt128? ToUInt128(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
static UInt128? ToUInt128Safe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// Complex
Complex? ToComplex(
NumberStyles style = Styles.Float,
IFormatProvider? provider = null);
Complex? ToComplexSafe(
NumberStyles style = Styles.Float,
IFormatProvider? provider = null);
// Guid
Guid? ToGuid();
Guid? ToGuidSafe();
Guid? ToGuid(string format);
Guid? ToGuidSafe(string format);
Guid? ToGuid(ReadOnlySpan<char> format);
Guid? ToGuidSafe(ReadOnlySpan<char> format);
Guid? ToGuid(string[] formats);
Guid? ToGuidSafe(string[] formats);
// DateTime
DateTime? ToDateTime(
DateTimeStyles style = Styles.DateTime,
IFormatProvider? provider = null);
DateTime? ToDateTimeSafe(
DateTimeStyles style = Styles.DateTime,
IFormatProvider? provider = null);
DateTime? ToDateTime(
string format,
DateTimeStyles style = Styles.DateTime,
IFormatProvider? provider = null);
DateTime? ToDateTimeSafe(
string format,
DateTimeStyles style = Styles.DateTime,
IFormatProvider? provider = null);
// .NET Core/.NET
DateTime? ToDateTime(
ReadOnlySpan<char> format,
DateTimeStyles style = Styles.DateTime,
IFormatProvider? provider = null);
DateTime? ToDateTimeSafe(
ReadOnlySpan<char> format,
DateTimeStyles style = Styles.DateTime,
IFormatProvider? provider = null);
DateTime? ToDateTime(
string[] formats,
DateTimeStyles style = Styles.DateTime,
IFormatProvider? provider = null);
DateTime? ToDateTimeSafe(
string[] formats,
DateTimeStyles style = Styles.DateTime,
IFormatProvider? provider = null);
DateTime? ToUtcDateTime(
DateTimeStyles style = Styles.UtcDateTime,
IFormatProvider? provider = null);
DateTime? ToUtcDateTimeSafe(
DateTimeStyles style = Styles.UtcDateTime,
IFormatProvider? provider = null);
DateTime? ToUtcDateTimeFromUnixTimeSeconds(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
DateTime? ToUtcDateTimeFromUnixTimeSecondsSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
DateTime? ToUtcDateTimeFromUnixTimeMilliseconds(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
DateTime? ToUtcDateTimeFromUnixTimeMillisecondsSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// DateTimeOffset
DateTimeOffset? ToDateTimeOffset(
DateTimeStyles style = Styles.DateTimeOffset,
IFormatProvider? provider = null);
DateTimeOffset? ToDateTimeOffsetSafe(
DateTimeStyles style = Styles.DateTimeOffset,
IFormatProvider? provider = null);
DateTimeOffset? ToDateTimeOffset(
string format,
DateTimeStyles style = Styles.DateTimeOffset,
IFormatProvider? provider = null);
DateTimeOffset? ToDateTimeOffsetSafe(
string format,
DateTimeStyles style = Styles.DateTimeOffset,
IFormatProvider? provider = null);
// .NET Core/.NET
DateTimeOffset? ToDateTimeOffset(
ReadOnlySpan<char> format,
DateTimeStyles style = Styles.DateTimeOffset,
IFormatProvider? provider = null);
DateTimeOffset? ToDateTimeOffsetSafe(
ReadOnlySpan<char> format,
DateTimeStyles style = Styles.DateTimeOffset,
IFormatProvider? provider = null);
DateTimeOffset? ToDateTimeOffset(
string[] formats,
DateTimeStyles style = Styles.DateTimeOffset,
IFormatProvider? provider = null);
DateTimeOffset? ToDateTimeOffsetSafe(
string[] formats,
DateTimeStyles style = Styles.DateTimeOffset,
IFormatProvider? provider = null);
DateTimeOffset? ToDateTimeOffsetFromUnixTimeSeconds(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
DateTimeOffset? ToDateTimeOffsetFromUnixTimeSecondsSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
DateTimeOffset? ToDateTimeOffsetFromUnixTimeMilliseconds(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
DateTimeOffset? ToDateTimeOffsetFromUnixTimeMillisecondsSafe(
NumberStyles style = Styles.Integer,
IFormatProvider? provider = null);
// TimeSpan
TimeSpan? ToTimeSpan(
IFormatProvider? provider = null);
TimeSpan? ToTimeSpanSafe(
IFormatProvider? provider = null);
TimeSpan? ToTimeSpan(
string format,
TimeSpanStyles style = Styles.TimeSpan,
IFormatProvider? provider = null);
TimeSpan? ToTimeSpanSafe(
string format,
TimeSpanStyles style = Styles.TimeSpan,
IFormatProvider? provider = null);
// .NET Core/.NET
TimeSpan? ToTimeSpan(
ReadOnlySpan<char> format,
TimeSpanStyles style = Styles.TimeSpan,
IFormatProvider? provider = null);
TimeSpan? ToTimeSpanSafe(
ReadOnlySpan<char> format,
TimeSpanStyles style = Styles.TimeSpan,
IFormatProvider? provider = null);
TimeSpan? ToTimeSpan(
string[] formats,
TimeSpanStyles style = Styles.TimeSpan,
IFormatProvider? provider = null);
TimeSpan? ToTimeSpanSafe(
string[] formats,
TimeSpanStyles style = Styles.TimeSpan,
IFormatProvider? provider = null);
// DateOnly: .NET 6+
DateOnly? ToDateOnly(
DateTimeStyles style = Styles.DateOnly,
IFormatProvider? provider = null);
DateOnly? ToDateOnlySafe(
DateTimeStyles style = Styles.DateOnly,
IFormatProvider? provider = null);
DateOnly? ToDateOnly(
string format,
DateTimeStyles style = Styles.DateOnly,
IFormatProvider? provider = null);
DateOnly? ToDateOnlySafe(
string format,
DateTimeStyles style = Styles.DateOnly,
IFormatProvider? provider = null);
// .NET Core/.NET
DateOnly? ToDateOnly(
ReadOnlySpan<char> format,
DateTimeStyles style = Styles.DateOnly,
IFormatProvider? provider = null);
DateOnly? ToDateOnlySafe(
ReadOnlySpan<char> format,
DateTimeStyles style = Styles.DateOnly,
IFormatProvider? provider = null);
DateOnly? ToDateOnly(
string[] formats,
DateTimeStyles style = Styles.DateOnly,
IFormatProvider? provider = null);
DateOnly? ToDateOnlySafe(
string[] formats,
DateTimeStyles style = Styles.DateOnly,
IFormatProvider? provider = null);
// TimeOnly: .NET 6+
TimeOnly? ToTimeOnly(
DateTimeStyles style = Styles.TimeOnly,
IFormatProvider? provider = null);
TimeOnly? ToTimeOnlySafe(
DateTimeStyles style = Styles.TimeOnly,
IFormatProvider? provider = null);
TimeOnly? ToTimeOnly(
string format,
DateTimeStyles style = Styles.TimeOnly,
IFormatProvider? provider = null);
TimeOnly? ToTimeOnlySafe(
string format,
DateTimeStyles style = Styles.TimeOnly,
IFormatProvider? provider = null);
// .NET Core/.NET
TimeOnly? ToTimeOnly(
ReadOnlySpan<char> format,
DateTimeStyles style = Styles.TimeOnly,
IFormatProvider? provider = null);
TimeOnly? ToTimeOnlySafe(
ReadOnlySpan<char> format,
DateTimeStyles style = Styles.TimeOnly,
IFormatProvider? provider = null);
TimeOnly? ToTimeOnly(
string[] formats,
DateTimeStyles style = Styles.TimeOnly,
IFormatProvider? provider = null);
TimeOnly? ToTimeOnlySafe(
string[] formats,
DateTimeStyles style = Styles.TimeOnly,
IFormatProvider? provider = null);
SubmitChanges(). But you can use LINQPad's Util.WriteCsvCannot load type 'LINQPad.User.***' from cache error, use connection context menu Close all connections.BadDataException: You can ignore bad data by setting BadDataFound to null error, check Ignore bad data at Format section.CsvLINQPadDriver.txt log file to the %LOCALAPPDATA%\LINQPad\Logs for the LINQPad 5 or to the corresponding %LOCALAPPDATA%\LINQPad\Logs.* LINQPad folders. This file is never truncated.