Giter Site home page Giter Site logo

kungfux / lambdasql Goto Github PK

View Code? Open in Web Editor NEW

This project forked from serg046/lambdasql

0.0 2.0 0.0 615 KB

Provides possibility to create sql query based on entity type and build query using OOP style. It uses a member lambda expression to get column name and has corresponding methods for each sql clause.

License: MIT License

C# 100.00%

lambdasql's Introduction

LambdaSql

Build status NuGet version

Provides possibility to create sql query based on entity type and build query using OOP style. It uses a member lambda expression to get column name and has corresponding methods for each sql clause.

Structure

The main two types are SqlSelect and SqlFilter. SqlSelect contains logic to create select sql query and SqlFilter is used for some filter like where or having clauses. All features are immutable.

  • SqlSelect contract
SqlSelect<T> Extend(Func<ISqlSelectQueryBuilder, ISqlSelectQueryBuilder> decorationCallback);
Type EntityType { get; }  
string RawSql { get; }  
string ParametricSql { get; }  
DbParameter[] Parameters { get; }  
SqlSelect<T> Distinct();  
SqlSelect<T> AddFields(params Expression<Func<T, object>>[] fields);  
SqlSelect<T> GroupBy(params Expression<Func<T, object>>[] fields);  
SqlSelect<T> OrderBy(params Expression<Func<T, object>>[] fields);  
SqlSelect<T> InnerJoin<TLeft, TJoin>(...);  
SqlSelect<T> LeftJoin<TLeft, TJoin>(...);  
SqlSelect<T> RightJoin<TLeft, TJoin>(...);  
SqlSelect<T> FullJoin<TLeft, TJoin>(...);  
SqlSelect<T> Where(ISqlFilter filter);  
SqlSelect<T> Having(ISqlFilter filter);  
  • SqlFilter contract
string RawSql { get; }  
SqlParameter[] Parameters { get; }  
string ParametricSql { get; }  
SqlFilterField And<TFieldType>(...);  
SqlFilter<TEntity> And(SqlFilter<TEntity> filter);  
SqlFilterField Or<TFieldType>(...);  
SqlFilter<TEntity> Or(SqlFilter<TEntity> filter);  
SqlFilter<TEntity> AndGroup(SqlFilter<TEntity> filter);  
SqlFilter<TEntity> OrGroup(SqlFilter<TEntity> filter);  
  • SqlFilterField contract
TResult SatisfyLambda(Func<ISqlField, string> filter);  
TResult IsNull();  
TResult IsNotNull();  
TResult Like(string value);  
TResult EqualTo(TFieldType value);  
TResult EqualTo(Expression<Func<TEntity, TFieldType>> field);  
TResult NotEqualTo(TFieldType value);  
TResult NotEqualTo(Expression<Func<TEntity, TFieldType>> field);  
TResult GreaterThan(TFieldType value);  
TResult GreaterThan(Expression<Func<TEntity, TFieldType>> field);  
TResult GreaterThanOrEqual(TFieldType value);  
TResult GreaterThanOrEqual(Expression<Func<TEntity, TFieldType>> field);  
TResult LessThan(TFieldType value);  
TResult LessThan(Expression<Func<TEntity, TFieldType>> field);  
TResult LessThanOrEqual(TFieldType value);  
TResult LessThanOrEqual(Expression<Func<TEntity, TFieldType>> field);  
TResult In(params TFieldType[] values);  
TResult NotIn(params TFieldType[] values);  

Usage

  • Entity types
public class Person
{
    public int Id { get; }
    public string Name { get; }
    public int PassportId { get; }
}

public class Passport
{
    public int Id { get; }
    public string Number { get; }
}
  • Simple query
var qry = new SqlSelect<Person>()
    .AddFields(p => p.Id)
    .Where(SqlFilter<Person>.From(p => p.Name).EqualTo("Sergey"));
    
Console.WriteLine(qry.ParametricSql);
Console.WriteLine("---");
Console.WriteLine(string.Join("; ", qry.Parameters
    .Select(p => $"Name = {p.ParameterName}, Value = {p.Value}")));
SELECT
    pe.Id
FROM
    Person pe
WHERE
    pe.Name = @w0
---
Name = @w0, Value = Sergey
  • Group by and having clauses
var qry = new SqlSelect<Person>()
    .AddFields(p => p.Name)
    .AddFields(SqlField<Person>.Count(p => p.Name))
    .Where(SqlFilter<Person>.From(p => p.Id).GreaterThan(5))
    .GroupBy(p => p.Name)
    .Having(SqlFilter<Person>.From(p => p.Name).EqualTo("Sergey"));

Console.WriteLine(qry.ParametricSql);
Console.WriteLine("---");
Console.WriteLine(string.Join("; ", qry.Parameters
    .Select(p => $"Name = {p.ParameterName}, Value = {p.Value}")));
SELECT
    pe.Name, COUNT(pe.Name)
FROM
    Person pe
WHERE
    pe.Id > @w0
GROUP BY
    pe.Name
HAVING
    pe.Name = @h0
---
Name = @w0, Value = 5; Name = @h0, Value = Sergey
  • Nested query
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}")));
SELECT
    inner.Name
FROM
(
    SELECT
        pe.Id, pe.Name
    FROM
        Person pe
    WHERE
        pe.Name = @w0
) AS inner
---
Name = @w0, Value = Sergey
  • Inner join
var joinByLambda = new SqlSelect<Person>()
    .InnerJoin<Person, Passport>((person, passport) => person.PassportId == passport.Id);
var joinByFilter = new SqlSelect<Person>()
    .InnerJoin<Passport>(SqlFilter<Passport>.From(p => p.Id).EqualTo<Person>(p => p.PassportId));

Console.WriteLine(joinByLambda.ParametricSql);
Console.WriteLine("---");
Console.WriteLine(joinByFilter.ParametricSql);
SELECT
    *
FROM
    Person pe
INNER JOIN
    Passport pa ON pe.PassportId = pa.Id
---
SELECT
    *
FROM
    Person pe
INNER JOIN
    Passport pa ON pa.Id = pe.PassportId

Extensibility

  • SqlSelectQueryBuilder contract
ISqlSelectQueryBuilder ModifySelectFields(ModifyQueryPartCallback modificationCallback);
ISqlSelectQueryBuilder ModifyJoins(ModifyQueryPartCallback modificationCallback);
ISqlSelectQueryBuilder ModifyWhereFilters(ModifyQueryPartCallback modificationCallback);
ISqlSelectQueryBuilder ModifyGroupByFields(ModifyQueryPartCallback modificationCallback);
ISqlSelectQueryBuilder ModifyHavingFilters(ModifyQueryPartCallback modificationCallback);
ISqlSelectQueryBuilder ModifyOrderByFields(ModifyQueryPartCallback modificationCallback);
ISqlSelectQueryBuilder Modify(ModifyQueryPartCallback modificationCallback); //To modify the whole query
  • MySql Limit
public static ISqlSelect Limit(this ISqlSelect select, int count, int? offset = null)
{
    if (count <= 0)
    {
        throw new ArgumentException("Parameter \"count\" must be a possitive number");
    }
    if (offset.HasValue && offset <= 0)
    {
        throw new ArgumentException("Parameter \"offset\" must be a possitive number");
    }
    return offset == null
        ? select.Extend(queryBuilder => queryBuilder.Modify(query => $"{query}{Environment.NewLine}LIMIT {count}"))
        : select.Extend(queryBuilder => queryBuilder.Modify(query => $"{query}{Environment.NewLine}LIMIT {count} OFFSET {offset}"));
}

static void Main(string[] args)
{
    Console.WriteLine(new SqlSelect<Person>().Limit(10).RawSql);
    Console.WriteLine();
    Console.WriteLine(new SqlSelect<Person>().Limit(10, 5).RawSql);
}
SELECT
    *
FROM
    Person pe
LIMIT 10

SELECT
    *
FROM
    Person pe
LIMIT 10 OFFSET 5
  • Oracle ROWNUM
public static ISqlSelect Top(this ISqlSelect select, int count)
{
    if (count <= 0)
    {
        throw new ArgumentException("Parameter \"count\" must be a possitive number");
    }
    return select.Extend(queryBuilder => queryBuilder.ModifyWhereFilters(where => where.Length == 0
        ? $"{Environment.NewLine}WHERE{Environment.NewLine}    ROWNUM <= {count}"
        : $"{where} AND ROWNUM <= {count}"));
}

static void Main(string[] args)
{
    Console.WriteLine(new SqlSelect<Person>().Top(10).RawSql);
    Console.WriteLine();
    Console.WriteLine(new SqlSelect<Person>()
        .Where(SqlFilter<Person>.From(person => person.Name).EqualTo("Sergey"))
        .Top(10).RawSql);
}
SELECT
    *
FROM
    Person pe
WHERE
    ROWNUM <= 10

SELECT
    *
FROM
    Person pe
WHERE
    pe.Name = 'Sergey' AND ROWNUM <= 10

lambdasql's People

Contributors

serg046 avatar

Watchers

James Cloos avatar Alexander Fuks avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.