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);
}
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