Search code examples
c#sqlcode-generationsqlbuilder

Build sql query object by lambda


Can anybody advise a lib to build a raw sql code by lambda expression? Do not advise EF and Linq2sql because it doesn't provide a control over query.

Something like this. It's the code from my own library. But I don't wish to support this if there is another good solution for this case.

[Fact]
public void TotalTest()
{
    var countFld = SqlField<Person>.Count(p => p.LastName);
    var select = new SqlSelect<Person>()
        .AddFields(p => p.LastName, p => p.Name)
        .AddFields<Passport>(p => p.Number)
        .AddField(countFld)
        .InnerJoin<Person, Passport>((person, passport) => person.Id == passport.PersonId)
        .Where(SqlFilter<Passport>.From(p => p.Number).IsNotNull().And(p => p.Number).NotEqualTo("3812-808316"))
        .GroupBy(p => p.LastName)
        .Having(SqlFilter<Person>.From<int>(countFld).GreaterThan(2))
        .OrderBy(p => p.LastName);

    var expected =
@"SELECT
    pe.LastName, pe.Name, pa.Number, COUNT(pe.LastName)
FROM
    Person pe
INNER JOIN
    Passport pa ON pe.Id = pa.PersonId
WHERE
    pa.Number IS NOT NULL AND pa.Number <> '3812-808316'
GROUP BY
    pe.LastName
HAVING
    COUNT(pe.LastName) > 2
ORDER BY
    pe.LastName";
    Assert.Equal(expected, select.CommandText);
}

Solution

  • I've published the lib to GitHub with nuget package. It contains basic scenarios and will be updated as necessary. Setting fields, where, group by, having, order by, joins, nested queries are already supported.

    https://github.com/Serg046/LambdaSql

    Example:

    var qry = new SqlSelect
    (
        new SqlSelect<Person>()
            .AddFields(p => p.Id, p => p.Name)
            .Where(SqlFilter<Person>.From(p => p.Name).EqualTo("Sergey"))
        , new SqlAlias("inner")
    ).AddFields<Person>(p => p.Name);
    
    Console.WriteLine(qry.ParametricSql);
    Console.WriteLine("---");
    Console.WriteLine(string.Join("; ", qry.Parameters
        .Select(p => $"Name = {p.ParameterName}, Value = {p.Value}")));
    

    Output:

    SELECT
        inner.Name
    FROM
    (
        SELECT
            pe.Id, pe.Name
        FROM
            Person pe
        WHERE
            pe.Name = @w0
    ) AS inner
    ---
    Name = @w0, Value = Sergey