├── Spry.Tests
├── TestDatabase.mdf
├── TestDatabase_log.ldf
├── Dto
│ ├── Customer.cs
│ └── CustomerAddress.cs
├── Spry.Tests.csproj
├── BaseTest.cs
├── Benchmarks
│ └── DapperDirectVsSpryInsertBenchmark.cs
├── RepositoryTest.cs
└── CustomerRepository.cs
├── Spry
├── IBuilder.cs
├── Table
│ ├── InnerJoin.cs
│ ├── FullOuterJoin.cs
│ ├── LeftOuterJoin.cs
│ ├── RightOuterJoin.cs
│ ├── IConditionItem.cs
│ ├── Join.cs
│ ├── SpryTableConditions.cs
│ └── SpryTable.cs
├── Delete
│ ├── SpryDelete.cs
│ └── SpryDeleteTable.cs
├── Select
│ ├── SprySelect.cs
│ ├── SprySelectColumn.cs
│ └── SprySelectTable.cs
├── IExecutable.cs
├── Spry.csproj
├── Insert
│ ├── SpryInsertTable.cs
│ ├── SpryInsert.cs
│ └── InsertValue.cs
├── Update
│ ├── SpryUpdate.cs
│ ├── SpryUpdateTable.cs
│ └── UpdateValue.cs
├── SqlExecutor.cs
├── Spry.cs
├── SpryExpression.cs
├── SpryParameter.cs
└── Where
│ └── Where.cs
├── .gitignore
├── Spry.Console
├── Spry.Console.csproj
└── Program.cs
├── .github
└── workflows
│ ├── build.yml
│ └── release.yml
├── LICENSE
├── Spry.sln
└── README.MD
/Spry.Tests/TestDatabase.mdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vigneshmsft/Spry/HEAD/Spry.Tests/TestDatabase.mdf
--------------------------------------------------------------------------------
/Spry.Tests/TestDatabase_log.ldf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vigneshmsft/Spry/HEAD/Spry.Tests/TestDatabase_log.ldf
--------------------------------------------------------------------------------
/Spry/IBuilder.cs:
--------------------------------------------------------------------------------
1 | namespace Spry
2 | {
3 | public abstract class Builder
4 | {
5 | internal abstract string Build();
6 | }
7 |
8 | public abstract class Buildable
9 | {
10 | internal abstract string BuildImpl();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Spry.Tests/Dto/Customer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Spry.Tests.Dto
4 | {
5 | public class Customer
6 | {
7 | public int CustomerId { get; set; }
8 |
9 | public string Name { get; set; }
10 |
11 | public DateTime DateOfBirth { get; set; }
12 |
13 | public CustomerAddress Address { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio.
3 | ################################################################################
4 |
5 | /Spry/bin
6 | /Spry/obj
7 | /Spry.Console/bin
8 | /Spry.Console/obj
9 | /Spry.Tests/bin
10 | /Spry.Tests/obj
11 | /TestResults
12 | *.nupkg
13 | /packages
14 | /.vs/
15 | /.vs/**/
16 | *.suo
17 |
--------------------------------------------------------------------------------
/Spry.Tests/Dto/CustomerAddress.cs:
--------------------------------------------------------------------------------
1 | namespace Spry.Tests.Dto
2 | {
3 | public class CustomerAddress
4 | {
5 | public int CustomerAddressId { get; set; }
6 |
7 | public int CustomerId { get; set; }
8 |
9 | public string LineOne { get; set; }
10 |
11 | public string City { get; set; }
12 |
13 | public string Country { get; set; }
14 |
15 | public string PostCode { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Spry.Console/Spry.Console.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.2
5 | false
6 |
7 | Exe
8 | Spry.Console.Program
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Spry/Table/InnerJoin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Spry.Select;
3 |
4 | namespace Spry.Table
5 | {
6 | public class InnerJoin : Join
7 | {
8 | public InnerJoin(SprySelect spry, SprySelectTable tableOne, SprySelectTable tableTwo)
9 | : base(spry, tableOne, tableTwo)
10 | {
11 |
12 | }
13 |
14 | internal override string BuildImpl()
15 | {
16 | return "INNER JOIN " + TableTwo.BuildImpl() + OnCondition + Environment.NewLine;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Spry/Table/FullOuterJoin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Spry.Select;
3 |
4 | namespace Spry.Table
5 | {
6 | public class FullOuterJoin : Join
7 | {
8 | public FullOuterJoin(SprySelect spry, SprySelectTable tableOne, SprySelectTable tableTwo)
9 | : base(spry, tableOne, tableTwo)
10 | {
11 | }
12 |
13 | internal override string BuildImpl()
14 | {
15 | return "FULL OUTER JOIN " + TableTwo.BuildImpl() + OnCondition + Environment.NewLine;
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | pull_request:
6 | branches: [ master ]
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/checkout@v2
14 | name: Checkout Repository
15 |
16 | - name: Use .NET Core 3.1.301
17 | uses: actions/setup-dotnet@v1
18 | with:
19 | dotnet-version: 3.1.301
20 |
21 | - name: dotnet restore
22 | run: dotnet restore /nologo
23 |
24 | - name: dotnet build
25 | run: dotnet build -c Release --no-restore --nologo
26 |
--------------------------------------------------------------------------------
/Spry/Table/LeftOuterJoin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Spry.Select;
3 |
4 | namespace Spry.Table
5 | {
6 | public class LeftOuterJoin : Join
7 | {
8 | public LeftOuterJoin(SprySelect spry, SprySelectTable tableOne, SprySelectTable tableTwo)
9 | : base(spry, tableOne, tableTwo)
10 | {
11 | }
12 |
13 | internal override string BuildImpl()
14 | {
15 | return "LEFT OUTER JOIN " + TableTwo.BuildImpl() + OnCondition + Environment.NewLine;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Spry/Table/RightOuterJoin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Spry.Select;
3 |
4 | namespace Spry.Table
5 | {
6 | public class RightOuterJoin : Join
7 | {
8 | public RightOuterJoin(SprySelect spry, SprySelectTable tableOne, SprySelectTable tableTwo)
9 | : base(spry, tableOne, tableTwo)
10 | {
11 | }
12 |
13 | internal override string BuildImpl()
14 | {
15 | return "RIGHT OUTER JOIN " + TableTwo.BuildImpl() + OnCondition + Environment.NewLine;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Spry/Delete/SpryDelete.cs:
--------------------------------------------------------------------------------
1 | using Spry.Table;
2 |
3 | namespace Spry.Delete
4 | {
5 | public class SpryDelete
6 | {
7 | internal SpryDelete() { }
8 |
9 | private SpryDeleteTable _table;
10 |
11 | public SpryDeleteTable From(string tableName, string schema = "dbo")
12 | {
13 | _table = new SpryDeleteTable(this, tableName, schema);
14 | return _table;
15 | }
16 |
17 | public string Build()
18 | {
19 | return "DELETE FROM " + _table.BuildImpl();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Spry/Select/SprySelect.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Spry.Select
4 | {
5 | public sealed class SprySelect
6 | {
7 | private SprySelectColumn _column;
8 | private SprySelect()
9 | {
10 |
11 | }
12 |
13 | public static SprySelectColumn Select()
14 | {
15 | var spry = new SprySelect();
16 | return spry._column = new SprySelectColumn(spry);
17 | }
18 |
19 | public string Build()
20 | {
21 | return "SELECT" + Environment.NewLine + _column.BuildImpl();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Spry.Tests/Spry.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.2
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Spry/IExecutable.cs:
--------------------------------------------------------------------------------
1 | namespace Spry
2 | {
3 | using System.Collections.Generic;
4 | using System.Data;
5 |
6 | public interface IExecutable
7 | {
8 | int Execute(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null);
9 |
10 | IEnumerable Query(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null);
11 |
12 | IEnumerable Query(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null);
13 |
14 | TColType ExecuteScalar(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null);
15 | }
16 | }
--------------------------------------------------------------------------------
/Spry/Spry.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard20
5 | 1.0.6
6 | Vignesh.N
7 | https://github.com/vigneshmsft/Spry/blob/master/LICENSE
8 | https://github.com/vigneshmsft/Spry
9 | https://github.com/vigneshmsft/Spry
10 | dapper spry database micro-orm orm sql-server sql query-builder fluent-query-builder query dapper-extensions
11 | Spry - fluent CRUD queries using Dapper
12 | v1.0.6
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Spry/Insert/SpryInsertTable.cs:
--------------------------------------------------------------------------------
1 | using Spry.Table;
2 |
3 | namespace Spry.Insert
4 | {
5 | internal class SpryInsertTable : SpryTable>
6 | {
7 | private readonly SpryInsert _spry;
8 |
9 | public SpryInsertTable(string tableName, string schema, SpryInsert spry)
10 | : base(tableName, schema)
11 | {
12 | _spry = spry;
13 | }
14 |
15 | protected override SpryInsertTable TableImpl
16 | {
17 | get { return this; }
18 | }
19 |
20 | public override string Build()
21 | {
22 | var returnString = _spry.Build();
23 |
24 | if (string.IsNullOrWhiteSpace(ExtraQuery))
25 | {
26 | returnString += ExtraQuery;
27 | }
28 |
29 | return returnString;
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/Spry/Table/IConditionItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Spry.Where;
4 |
5 | namespace Spry.Table
6 | {
7 | public interface IConditionItem where TTable : SpryTable
8 | {
9 | Where Where(Expression> columnExpression, string colPrefix = null);
10 | Where AndWhere(Expression> columnExpression, string colPrefix = null);
11 | Where OrWhere(Expression> columnExpression, string colPrefix = null);
12 |
13 | Where Where(string columnName);
14 | Where OrWhere(string columnName);
15 | Where AndWhere(string columnName);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Spry/Insert/SpryInsert.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Spry.Table;
3 |
4 | namespace Spry.Insert
5 | {
6 | public class SpryInsert
7 | {
8 | private InsertValue _value;
9 | private SpryInsertTable _spryTable;
10 | private string _table;
11 | private string _dbSchema;
12 |
13 | private SpryInsert()
14 | {
15 |
16 | }
17 |
18 | public static InsertValue Insert(string tableName, string dbSchema)
19 | {
20 | var spry = new SpryInsert
21 | {
22 | _table = tableName,
23 | _dbSchema = dbSchema,
24 | };
25 |
26 | spry._spryTable = new SpryInsertTable(tableName, dbSchema, spry);
27 | return spry._value = new InsertValue(spry, spry._spryTable);
28 | }
29 |
30 | public string Build()
31 | {
32 | return "INSERT INTO " + _dbSchema + "." + _table + Environment.NewLine + _value.BuildImpl();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | publish_nuget:
9 | if: ${{ github.event.release.target_commitish == 'master' && !github.event.release.draft}}
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/checkout@v2
14 | name: Checkout Repository
15 |
16 | - name: Use .NET Core 3.1.301
17 | uses: actions/setup-dotnet@v1
18 | with:
19 | dotnet-version: 3.1.301
20 |
21 | - name: dotnet restore
22 | run: dotnet restore /nologo
23 |
24 | - name: dotnet build & pack
25 | run: |
26 | dotnet build -c Release --no-restore --nologo
27 | dotnet pack Spry/Spry.csproj -c Release --no-build --nologo -o package
28 |
29 | - name: dotnet push to NuGet
30 | working-directory: package
31 | run: |
32 | dotnet nuget push ${PACKAGE_NAME} --api-key ${NUGET_API_KEY} --source https://api.nuget.org/v3/index.json
33 | env:
34 | PACKAGE_NAME: ${{ format('Spry.{0}.nupkg', github.event.release.tag_name) }}
35 | NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Vignesh.N
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Spry/Update/SpryUpdate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Spry.Update
4 | {
5 | public class SpryUpdate
6 | {
7 | private string _table;
8 | private string _dbSchema;
9 | private UpdateValue _value;
10 | private SpryUpdateTable _spryTable;
11 |
12 | internal SpryUpdate()
13 | {
14 | }
15 |
16 | public static UpdateValue Update(string tableName, string dbSchema)
17 | {
18 | var spry = new SpryUpdate
19 | {
20 | _table = tableName,
21 | _dbSchema = dbSchema,
22 | };
23 |
24 | spry._spryTable = new SpryUpdateTable(spry, tableName, dbSchema);
25 | return spry._value = new UpdateValue(spry, spry._spryTable);
26 | }
27 |
28 | public string Build()
29 | {
30 | return "UPDATE " + _dbSchema + "." + _table + Environment.NewLine + "SET" + Environment.NewLine
31 | + _value.BuildImpl()
32 | + _spryTable.BuildImpl();
33 | }
34 | }
35 |
36 |
37 | }
--------------------------------------------------------------------------------
/Spry/Table/Join.cs:
--------------------------------------------------------------------------------
1 | using Spry.Select;
2 |
3 | namespace Spry.Table
4 | {
5 | public abstract class Join
6 | {
7 | protected readonly SprySelect Spry;
8 | protected readonly SprySelectTable TableOne;
9 | protected readonly SprySelectTable TableTwo;
10 | protected string OnCondition;
11 |
12 | protected Join(SprySelect spry, SprySelectTable tableOne, SprySelectTable tableTwo)
13 | {
14 | TableTwo = tableTwo;
15 | TableOne = tableOne;
16 | Spry = spry;
17 | }
18 |
19 | public virtual SprySelectTable On(string colOne, string colTwo)
20 | {
21 | OnCondition = " ON " + colOne + " = " + colTwo;
22 | return TableOne;
23 | }
24 |
25 | public virtual SprySelectTable On(string onCondition)
26 | {
27 | OnCondition = onCondition;
28 | return TableOne;
29 | }
30 |
31 | public virtual string Build()
32 | {
33 | return Spry.Build();
34 | }
35 |
36 | internal abstract string BuildImpl();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Spry.Tests/BaseTest.cs:
--------------------------------------------------------------------------------
1 | using System.Data.SqlClient;
2 |
3 | namespace Spry.Tests
4 | {
5 | public abstract class BaseTest
6 | {
7 | private const string CONNECTION_STRING = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Workspace\Spry\Spry.Tests\TestDatabase.mdf;Integrated Security=True;Connect Timeout=30";
8 |
9 | protected const string CUSTOMER_TABLE = @"Customer";
10 |
11 | public SqlConnection CreateConnection()
12 | {
13 | var connection = new SqlConnection(CONNECTION_STRING);
14 | connection.Open();
15 | return connection;
16 | }
17 | }
18 |
19 | public interface ISqlConnectionFactory
20 | {
21 | SqlConnection CreateConnection();
22 | }
23 |
24 | public class TestConnectionFactory : ISqlConnectionFactory
25 | {
26 | private const string CONNECTION_STRING = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Workspace\Spry\Spry.Tests\TestDatabase.mdf;Integrated Security=True;Connect Timeout=30";
27 |
28 | public SqlConnection CreateConnection()
29 | {
30 | var connection = new SqlConnection(CONNECTION_STRING);
31 | connection.Open();
32 | return connection;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Spry/Update/SpryUpdateTable.cs:
--------------------------------------------------------------------------------
1 | using Spry.Table;
2 |
3 | namespace Spry.Update
4 | {
5 | public class SpryUpdateTable : SpryTable>
6 | {
7 | private readonly SpryUpdate _spry;
8 |
9 | internal SpryUpdateTable(SpryUpdate spry, string tableName, string schema)
10 | : base(tableName, schema)
11 | {
12 | _spry = spry;
13 | }
14 |
15 | protected override SpryUpdateTable TableImpl
16 | {
17 | get { return this; }
18 | }
19 |
20 | public override string Build()
21 | {
22 | return _spry.Build();
23 | }
24 |
25 | internal string BuildImpl()
26 | {
27 | string returnString = null;
28 |
29 | if (WhereCondition != null)
30 | {
31 | returnString += "WHERE " + WhereCondition.BuildImpl();
32 |
33 | foreach (var andCondition in AndConditions)
34 | {
35 | returnString += " AND " + andCondition.BuildImpl();
36 | }
37 |
38 | foreach (var orCondition in OrConditions)
39 | {
40 | returnString += " OR " + orCondition.BuildImpl();
41 | }
42 |
43 | }
44 |
45 | return returnString;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Spry/SqlExecutor.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Data;
3 | using Dapper;
4 |
5 | namespace Spry
6 | {
7 | public class SqlExecutor : IExecutable
8 | {
9 | private readonly string _query;
10 |
11 | public SqlExecutor(string query)
12 | {
13 | _query = query;
14 | }
15 |
16 | public int Execute(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
17 | {
18 | return connection.Execute(_query, parameters, commandType: commandType);
19 | }
20 |
21 | public IEnumerable Query(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
22 | {
23 | return connection.Query(_query, parameters, commandType: commandType);
24 | }
25 |
26 | public IEnumerable Query(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
27 | {
28 | return connection.Query(_query, parameters, commandType: commandType);
29 | }
30 |
31 | public TColType ExecuteScalar(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
32 | {
33 | return connection.ExecuteScalar(_query, parameters, commandType: commandType);
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/Spry/Spry.cs:
--------------------------------------------------------------------------------
1 | using Spry.Delete;
2 | using Spry.Insert;
3 | using Spry.Select;
4 | using Spry.Update;
5 |
6 | namespace Spry
7 | {
8 | public static class Spry
9 | {
10 | public static SprySelectColumn Select()
11 | {
12 | return SprySelect.Select();
13 | }
14 |
15 | public static SprySelectColumn Select()
16 | {
17 | return SprySelect.Select();
18 | }
19 |
20 | public static InsertValue InsertInto(string tableName, string dbSchema = "dbo")
21 | {
22 | return SpryInsert.Insert(tableName, dbSchema);
23 | }
24 |
25 | public static InsertValue InsertInto(string tableName, string dbSchema = "dbo")
26 | {
27 | return SpryInsert.Insert(tableName, dbSchema);
28 | }
29 |
30 | public static UpdateValue Update(string tableName, string dbSchema = "dbo")
31 | {
32 | return SpryUpdate.Update(tableName, dbSchema);
33 | }
34 |
35 | public static UpdateValue Update(string tableName, string dbSchema = "dbo")
36 | {
37 | return SpryUpdate.Update(tableName, dbSchema);
38 | }
39 |
40 | public static SpryDelete Delete()
41 | {
42 | return new SpryDelete();
43 | }
44 |
45 | public static SpryDelete Delete()
46 | {
47 | return new SpryDelete();
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/Spry/Delete/SpryDeleteTable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Spry.Table;
3 |
4 | namespace Spry.Delete
5 | {
6 | public class SpryDeleteTable : SpryTable>
7 | {
8 | private readonly SpryDelete _spry;
9 |
10 | internal SpryDeleteTable(SpryDelete spry, string tableName, string schema = "dbo")
11 | : base(tableName, schema)
12 | {
13 | _spry = spry;
14 | }
15 |
16 | protected override SpryDeleteTable TableImpl
17 | {
18 | get { return this; }
19 | }
20 |
21 | public override string Build()
22 | {
23 | return _spry.Build();
24 | }
25 |
26 | internal string BuildImpl()
27 | {
28 | string returnString = BuildImpl(this);
29 |
30 | returnString += Environment.NewLine;
31 |
32 | if (WhereCondition != null)
33 | {
34 | returnString += "WHERE " + WhereCondition.BuildImpl();
35 |
36 | foreach (var andCondition in AndConditions)
37 | {
38 | returnString += " AND " + andCondition.BuildImpl();
39 | }
40 |
41 | foreach (var orCondition in OrConditions)
42 | {
43 | returnString += " OR " + orCondition.BuildImpl();
44 | }
45 | }
46 |
47 | if (!string.IsNullOrWhiteSpace(ExtraQuery))
48 | {
49 | returnString += ExtraQuery;
50 | }
51 |
52 | return returnString;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Spry.Console/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Spry.Console
2 | {
3 | using System;
4 |
5 | public class Program
6 | {
7 | public static void Main(string[] args)
8 | {
9 | var myDto = new MyDto { Id = 1, IsDeleted = true };
10 |
11 | Spry.Select().Column(_ => myDto.Id).Column(_ => myDto.IsDeleted).From("tt")
12 | .InnerJoin("table2", "audit").On("c1", "d1")
13 | .InnerJoin("table3", "audit").On("c2", "d2")
14 | .InnerJoin("table4", "audit").On("c4", "d2")
15 | .InSchema("review")
16 | .Where(_ => myDto.Id).EqualTo(1)
17 | .AndWhere(_ => myDto.Id).InBetween(1, 10)
18 | .AndWhere(_ => myDto.Id).GreaterThan(5)
19 | .Build();
20 |
21 | Spry.InsertInto("tableOne", "review")
22 | .Value("One", 1)
23 | .Value(_ => myDto.Id)
24 | .OutputIdentity()
25 | .Execute(null);
26 |
27 | Spry.Update("tableOne")
28 | .Set(_ => myDto.Id)
29 | .Where("id").EqualTo(1)
30 | .Execute(null);
31 |
32 | Console.ReadLine();
33 | }
34 | }
35 |
36 | public class MyDto
37 | {
38 | public int Id { get; set; }
39 |
40 | public string Name { get; set; }
41 |
42 | public DateTime Today { get; set; }
43 |
44 | public bool IsDeleted { get; set; }
45 | }
46 |
47 | public enum EvidenceStatus : uint
48 | {
49 | NotApplicable = 0,
50 |
51 | Requested = 1,
52 |
53 | Awaiting = 2,
54 |
55 | Received = 3
56 | }
57 | }
--------------------------------------------------------------------------------
/Spry/SpryExpression.cs:
--------------------------------------------------------------------------------
1 | namespace Spry
2 | {
3 | using System;
4 | using System.Linq.Expressions;
5 |
6 | internal static class SpryExpression
7 | {
8 | internal static string GetColumnName(Expression> columnExpression)
9 | {
10 | var memberExpression = columnExpression.Body as MemberExpression;
11 |
12 | if (memberExpression == null)
13 | {
14 | var contantExpression = columnExpression.Body as ConstantExpression;
15 |
16 | if (contantExpression == null)
17 | throw new ArgumentException("Invalid Column Expression");
18 |
19 | return Convert.ToString(contantExpression.Value);
20 | }
21 |
22 | return memberExpression.Member.Name;
23 | }
24 |
25 | internal static object GetColumnValue(Expression> columnExpression)
26 | {
27 | Expression memberExpression = columnExpression.Body as MemberExpression;
28 |
29 | if (memberExpression == null)
30 | {
31 | var contantExpression = columnExpression.Body as ConstantExpression;
32 |
33 | if (contantExpression == null)
34 | throw new ArgumentException("Invalid Column Expression");
35 |
36 | memberExpression = contantExpression;
37 | }
38 |
39 | var valueExpression = Expression.Convert(memberExpression, typeof(TProperty));
40 |
41 | var valueFunc = Expression.Lambda>(valueExpression).Compile();
42 |
43 | return valueFunc();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Spry/SpryParameter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Spry
6 | {
7 | public class SpryParameter
8 | {
9 | public SpryParameter(string name, object value)
10 | {
11 | Name = name;
12 | Value = value;
13 | }
14 |
15 | public string Name { get; set; }
16 |
17 | public object Value { get; set; }
18 | }
19 |
20 | public class SpryParameters : IEnumerable>
21 | {
22 | private readonly List _parameters = new List();
23 |
24 | public SpryParameters Add(string name, object value)
25 | {
26 | _parameters.Add(new SpryParameter(name, value));
27 | return this;
28 | }
29 |
30 | public SpryParameters Add(SpryParameter parameter)
31 | {
32 | _parameters.Add(parameter);
33 | return this;
34 | }
35 |
36 | public IEnumerable Parameters
37 | {
38 | get { return _parameters; }
39 | }
40 |
41 | public void Add(SpryParameters parameters)
42 | {
43 | if (parameters != null && parameters._parameters.Any())
44 | {
45 | _parameters.AddRange(parameters._parameters);
46 | }
47 | }
48 |
49 | public IEnumerator> GetEnumerator()
50 | {
51 | foreach (var spryParameter in _parameters)
52 | {
53 | yield return new KeyValuePair(spryParameter.Name, spryParameter.Value);
54 | }
55 | }
56 |
57 | IEnumerator IEnumerable.GetEnumerator()
58 | {
59 | return GetEnumerator();
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Spry/Select/SprySelectColumn.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using System.Text;
4 |
5 | namespace Spry.Select
6 | {
7 | public sealed class SprySelectColumn
8 | {
9 | private readonly SprySelect _spry;
10 | private readonly StringBuilder _columnBuilder;
11 | private SprySelectTable _from;
12 |
13 | internal SprySelectColumn(SprySelect spry)
14 | {
15 | _columnBuilder = new StringBuilder();
16 | _spry = spry;
17 | }
18 |
19 | public SprySelectColumn Column(Expression> columnExpression)
20 | {
21 | var columnName = SpryExpression.GetColumnName(columnExpression);
22 | AppendColumn(columnName);
23 | return this;
24 | }
25 |
26 | public SprySelectColumn Column(Expression> columnExpression, string colPrefix)
27 | {
28 | var columnName = SpryExpression.GetColumnName(columnExpression);
29 | AppendColumn(colPrefix + "." + columnName);
30 | return this;
31 | }
32 |
33 | public SprySelectColumn Column(string columnName)
34 | {
35 | AppendColumn(columnName);
36 | return this;
37 | }
38 |
39 | public SprySelectTable From(string tableName)
40 | {
41 | return _from = new SprySelectTable(_spry, tableName);
42 | }
43 |
44 | private void AppendColumn(string columnName)
45 | {
46 | _columnBuilder.Append(columnName + ", ");
47 | }
48 |
49 | internal string BuildImpl()
50 | {
51 | RemoveTrailingComma();
52 | return _columnBuilder + Environment.NewLine + "FROM" + Environment.NewLine + _from.BuildImpl();
53 | }
54 |
55 | private void RemoveTrailingComma()
56 | {
57 | _columnBuilder.Length -= 2;
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Spry.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26730.3
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spry", "Spry\Spry.csproj", "{46AD06AC-F969-4402-8881-41C80607E756}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spry.Console", "Spry.Console\Spry.Console.csproj", "{A74CDA33-434D-4601-B0A9-9907475DAA51}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spry.Tests", "Spry.Tests\Spry.Tests.csproj", "{7D377906-64B6-4DC2-9F7E-489646B63CAC}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {46AD06AC-F969-4402-8881-41C80607E756}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {46AD06AC-F969-4402-8881-41C80607E756}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {46AD06AC-F969-4402-8881-41C80607E756}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {46AD06AC-F969-4402-8881-41C80607E756}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {A74CDA33-434D-4601-B0A9-9907475DAA51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {A74CDA33-434D-4601-B0A9-9907475DAA51}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {A74CDA33-434D-4601-B0A9-9907475DAA51}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {A74CDA33-434D-4601-B0A9-9907475DAA51}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {7D377906-64B6-4DC2-9F7E-489646B63CAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {7D377906-64B6-4DC2-9F7E-489646B63CAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {7D377906-64B6-4DC2-9F7E-489646B63CAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {7D377906-64B6-4DC2-9F7E-489646B63CAC}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {B22E3757-463F-41A6-AA28-47B27EA167C9}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/Spry.Tests/Benchmarks/DapperDirectVsSpryInsertBenchmark.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Dapper;
3 | using NUnit.Framework;
4 | using BenchmarkDotNet.Attributes;
5 | using BenchmarkDotNet.Running;
6 | using Spry.Tests.Dto;
7 |
8 |
9 | namespace Spry.Tests.Benchmarks
10 | {
11 | [TestFixture]
12 | public class DapperDirectVsSpryBenchmarkRunner
13 | {
14 | [Test]
15 | public void RunCustomerRepositoryBenchmarks()
16 | {
17 | var benchmark = BenchmarkRunner.Run();
18 | }
19 | }
20 |
21 | public class DapperDirectVsSpryInsertBenchmark
22 | {
23 | private readonly TestConnectionFactory _connectionFactory = new TestConnectionFactory();
24 | private readonly CustomerRepository _customerRepository;
25 |
26 | public DapperDirectVsSpryInsertBenchmark()
27 | {
28 | _customerRepository = new CustomerRepository(_connectionFactory);
29 | }
30 |
31 | [Benchmark]
32 | public void Spry_Insert_CheckOutputIdentity()
33 | {
34 | var customer = new Customer
35 | {
36 | DateOfBirth = DateTime.Today,
37 | Name = "John Doe"
38 | };
39 |
40 | customer.CustomerId = _customerRepository.Create(customer.Name, customer.DateOfBirth);
41 |
42 | Assert.IsTrue(customer.CustomerId > 0);
43 | }
44 |
45 | [Benchmark]
46 | public void Dapper_Insert_CheckOutputIdentity()
47 | {
48 | var customer = new Customer
49 | {
50 | DateOfBirth = DateTime.Today,
51 | Name = "John Doe"
52 | };
53 |
54 | using (var connection = _connectionFactory.CreateConnection())
55 | {
56 | customer.CustomerId = connection.ExecuteScalar(@"INSERT INTO dbo.Customer
57 | (Name, DateofBirth)
58 | OUTPUT Inserted.CustomerId
59 | VALUES (@Name, @DateOfBirth);", customer);
60 | }
61 |
62 | Assert.IsTrue(customer.CustomerId > 0);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Spry/Table/SpryTableConditions.cs:
--------------------------------------------------------------------------------
1 | using Spry.Where;
2 | using System;
3 | using System.Linq.Expressions;
4 |
5 | namespace Spry.Table
6 | {
7 | public abstract partial class SpryTable where TTable : SpryTable
8 | {
9 | public Where Where(Expression> columnExpression, string colPrefix = null)
10 | {
11 | var columnName = SpryExpression.GetColumnName(columnExpression);
12 | if (!string.IsNullOrWhiteSpace(colPrefix))
13 | {
14 | columnName = colPrefix + "." + columnName;
15 | }
16 | var where = new Where(TableImpl, Parameters, columnName);
17 | WhereCondition = where;
18 | return where;
19 | }
20 |
21 | public Where Where(string columnName)
22 | {
23 | var where = new Where(TableImpl, Parameters, columnName);
24 | WhereCondition = where;
25 | return where;
26 | }
27 |
28 | public Where AndWhere(Expression> columnExpression, string colPrefix = null)
29 | {
30 | var columnName = SpryExpression.GetColumnName(columnExpression);
31 | if (!string.IsNullOrWhiteSpace(colPrefix)) columnName = colPrefix + "." + columnName;
32 | var andWhere = new Where(TableImpl, Parameters, columnName);
33 | AndConditions.Add(andWhere);
34 | return andWhere;
35 | }
36 |
37 | public Where AndWhere(string columnName)
38 | {
39 | var andWhere = new Where(TableImpl, Parameters, columnName);
40 | AndConditions.Add(andWhere);
41 | return andWhere;
42 | }
43 |
44 | public Where OrWhere(Expression> columnExpression, string colPrefix = null)
45 | {
46 | var columnName = SpryExpression.GetColumnName(columnExpression);
47 | if (!string.IsNullOrWhiteSpace(colPrefix)) columnName = colPrefix + "." + columnName;
48 | var orWhere = new Where(TableImpl, Parameters, columnName);
49 | OrConditions.Add(orWhere);
50 | return orWhere;
51 | }
52 |
53 | public Where OrWhere(string columnName)
54 | {
55 | var orWhere = new Where(TableImpl, Parameters, columnName);
56 | OrConditions.Add(orWhere);
57 | return orWhere;
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Spry/Update/UpdateValue.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 | using System;
3 | using System.Text;
4 | using Spry.Table;
5 | using Spry.Where;
6 |
7 | namespace Spry.Update
8 | {
9 | public class UpdateValue : IConditionItem>
10 | {
11 | private readonly SpryUpdate _spry;
12 | private readonly SpryUpdateTable _table;
13 | private readonly StringBuilder _updateBuilder;
14 |
15 | public UpdateValue(SpryUpdate spry, SpryUpdateTable table)
16 | {
17 | _spry = spry;
18 | _table = table;
19 | _updateBuilder = new StringBuilder();
20 | }
21 |
22 | public UpdateValue Set(Expression> valueExpression)
23 | {
24 | var columnName = SpryExpression.GetColumnName(valueExpression);
25 | var value = SpryExpression.GetColumnValue(valueExpression);
26 | SetValueImpl(columnName, value);
27 | return this;
28 | }
29 |
30 | public UpdateValue Set(string columnName, object value)
31 | {
32 | SetValueImpl(columnName, value);
33 | return this;
34 | }
35 |
36 | private void SetValueImpl(string columnName, object value)
37 | {
38 | _table.AddParameter(columnName, value);
39 | _updateBuilder.AppendLine(columnName + " = @" + columnName + ", ");
40 | }
41 |
42 | public string Build()
43 | {
44 | return _spry.Build();
45 | }
46 |
47 | internal string BuildImpl()
48 | {
49 | RemoveTrailingCommas();
50 | return _updateBuilder + Environment.NewLine;
51 | }
52 |
53 | private void RemoveTrailingCommas()
54 | {
55 | _updateBuilder.Length -= 4;
56 | }
57 |
58 | public Where> Where(Expression> columnExpression, string colPrefix = null)
59 | {
60 | return _table.Where(columnExpression, colPrefix);
61 | }
62 |
63 | public Where> AndWhere(Expression> columnExpression, string colPrefix = null)
64 | {
65 | return _table.AndWhere(columnExpression, colPrefix);
66 | }
67 |
68 | public Where> OrWhere(Expression> columnExpression, string colPrefix = null)
69 | {
70 | return _table.OrWhere(columnExpression, colPrefix);
71 | }
72 |
73 | public Where> Where(string columnName)
74 | {
75 | return _table.Where(columnName);
76 | }
77 |
78 | public Where> OrWhere(string columnName)
79 | {
80 | return _table.OrWhere(columnName);
81 | }
82 |
83 | public Where> AndWhere(string columnName)
84 | {
85 | return _table.AndWhere(columnName);
86 | }
87 | }
88 | }
--------------------------------------------------------------------------------
/Spry/Where/Where.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Spry.Table;
5 |
6 | namespace Spry.Where
7 | {
8 | public class Where : Buildable where TTable : SpryTable
9 | {
10 | private readonly TTable _table;
11 | private readonly SpryParameters _parameters;
12 | private readonly string _columnName;
13 | private readonly string _columnParameterName;
14 | private readonly StringBuilder _whereBuilder;
15 |
16 | internal Where(TTable table, SpryParameters parameters, string columnName)
17 | {
18 | _whereBuilder = new StringBuilder();
19 | _table = table;
20 | _parameters = parameters;
21 | _columnName = columnName.Replace(";", "");
22 | _columnParameterName = CleanParameterName(_columnName);
23 | }
24 |
25 | public TTable EqualTo(TProperty value)
26 | {
27 | _parameters.Add(_columnParameterName, value);
28 | _whereBuilder.AppendFormat(@"{0} = @{1}", _columnName, _columnParameterName);
29 | return _table;
30 | }
31 |
32 | public TTable In(IEnumerable value)
33 | {
34 | _parameters.Add(_columnParameterName, value);
35 | _whereBuilder.AppendFormat(@"{0} IN @{1}", _columnName, _columnParameterName);
36 | return _table;
37 | }
38 |
39 | public TTable GreaterThan(TProperty value)
40 | {
41 | _parameters.Add(_columnParameterName, value);
42 | _whereBuilder.AppendFormat(@"{0} > @{1}", _columnName, _columnParameterName);
43 | return _table;
44 | }
45 |
46 | public TTable LessThan(TProperty value)
47 | {
48 | _parameters.Add(_columnParameterName, value);
49 | _whereBuilder.AppendFormat(@"{0} < @{1}", _columnName, _columnParameterName);
50 | return _table;
51 | }
52 |
53 | public TTable LessThanOrEqualTo(TProperty value)
54 | {
55 | _parameters.Add(_columnParameterName, value);
56 | _whereBuilder.AppendFormat(@"{0} <= @{1}", _columnName, _columnParameterName);
57 | return _table;
58 | }
59 |
60 | public TTable GreaterThanOrEqualTo(TProperty value)
61 | {
62 | _parameters.Add(_columnParameterName, value);
63 | _whereBuilder.AppendFormat(@"{0} >= @{1}", _columnName, _columnParameterName);
64 | return _table;
65 | }
66 |
67 | public TTable InBetween(TProperty valueOne, TProperty valueTwo)
68 | {
69 | _parameters.Add(_columnParameterName, valueOne);
70 | _parameters.Add(_columnParameterName + "valueTwo", valueTwo);
71 | _whereBuilder.AppendFormat(@"{0} BETWEEN @{1} AND @{1}valueTwo", _columnName, _columnParameterName);
72 | return _table;
73 | }
74 |
75 | internal override string BuildImpl()
76 | {
77 | return _whereBuilder + Environment.NewLine;
78 | }
79 |
80 | private static string CleanParameterName(string columnName)
81 | {
82 | return "p" + columnName.Replace("@", "").Replace(".", "").Replace(";", "").Replace("-", "");
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/Spry/Select/SprySelectTable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Spry.Table;
4 |
5 | namespace Spry.Select
6 | {
7 | public sealed class SprySelectTable : SpryTable>
8 | {
9 | private readonly SprySelect _spry;
10 |
11 | private readonly List> _joins;
12 |
13 | public SprySelectTable(SprySelect spry, string tableName, string tableAlias = null, string schema = "dbo")
14 | : base(tableName, schema, tableAlias)
15 | {
16 | _joins = new List>();
17 | _spry = spry;
18 | }
19 |
20 | public Join InnerJoin(string tableName, string tableAlias = null, string dbSchema = "dbo")
21 | {
22 | var innerJoin = new InnerJoin(_spry, this, new SprySelectTable(_spry, tableName, tableAlias, dbSchema));
23 | _joins.Add(innerJoin);
24 | return innerJoin;
25 | }
26 |
27 | public Join LeftOuterJoin(string tableName, string tableAlias = null, string dbSchema = "dbo")
28 | {
29 | var leftOuterJoin = new LeftOuterJoin(_spry, this, new SprySelectTable(_spry, tableName, tableAlias, dbSchema));
30 | _joins.Add(leftOuterJoin);
31 | return leftOuterJoin;
32 | }
33 |
34 | public Join RightOuterJoin(string tableName, string tableAlias = null, string dbSchema = "dbo")
35 | {
36 | var rightOuterJoin = new RightOuterJoin(_spry, this, new SprySelectTable(_spry, tableName, tableAlias, dbSchema));
37 | _joins.Add(rightOuterJoin);
38 | return rightOuterJoin;
39 | }
40 |
41 | public Join FullOuterJoin(string tableName, string tableAlias = null, string dbSchema = "dbo")
42 | {
43 | var fullOuterJoin = new FullOuterJoin(_spry, this, new SprySelectTable(_spry, tableName, tableAlias, dbSchema));
44 | _joins.Add(fullOuterJoin);
45 | return fullOuterJoin;
46 | }
47 |
48 | protected override SprySelectTable TableImpl
49 | {
50 | get { return this; }
51 | }
52 |
53 | public override string Build()
54 | {
55 | return _spry.Build();
56 | }
57 |
58 | internal string BuildImpl()
59 | {
60 | string returnString = BuildImpl(this);
61 |
62 | returnString += Environment.NewLine;
63 |
64 | foreach (var joins in _joins)
65 | {
66 | returnString += joins.BuildImpl();
67 | }
68 |
69 | if (WhereCondition != null)
70 | {
71 | returnString += "WHERE " + WhereCondition.BuildImpl();
72 |
73 | foreach (var andCondition in AndConditions)
74 | {
75 | returnString += " AND " + andCondition.BuildImpl();
76 | }
77 |
78 | foreach (var orCondition in OrConditions)
79 | {
80 | returnString += " OR " + orCondition.BuildImpl();
81 | }
82 | }
83 |
84 | if (!string.IsNullOrWhiteSpace(ExtraQuery))
85 | {
86 | returnString += ExtraQuery;
87 | }
88 |
89 | return returnString;
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Spry/Table/SpryTable.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Data;
3 |
4 | namespace Spry.Table
5 | {
6 | public abstract partial class SpryTable : IExecutable, IConditionItem where TTable : SpryTable
7 | {
8 | protected string TableName;
9 | protected string Schema;
10 | protected string Alias;
11 |
12 | internal readonly SpryParameters Parameters = new SpryParameters();
13 | protected Buildable WhereCondition;
14 | protected readonly List AndConditions = new List();
15 | protected readonly List OrConditions = new List();
16 | protected string ExtraQuery = null;
17 |
18 | protected abstract TTable TableImpl { get; }
19 |
20 | protected SpryTable(string tableName, string schema)
21 | : this(tableName, schema, null)
22 | {
23 | }
24 |
25 | protected SpryTable(string tableName, string schema, string alias)
26 | {
27 | TableName = tableName;
28 | Schema = schema;
29 | Alias = alias;
30 | }
31 |
32 | public virtual string Build()
33 | {
34 | return BuildImpl(this);
35 | }
36 |
37 | internal static string BuildImpl(SpryTable table)
38 | {
39 | string returnString = null;
40 |
41 | if (string.IsNullOrWhiteSpace(table.Alias))
42 | {
43 | returnString = table.Schema + "." + table.TableName;
44 | }
45 | else
46 | {
47 | returnString = string.Format("{0}.{1} AS {2}", table.Schema, table.TableName, table.Alias);
48 | }
49 | return returnString;
50 | }
51 |
52 | public TTable InSchema(string dbSchema)
53 | {
54 | Schema = dbSchema;
55 | return TableImpl;
56 | }
57 |
58 | public TTable As(string tableAlias)
59 | {
60 | Alias = tableAlias;
61 | return TableImpl;
62 | }
63 |
64 | public SpryTable AppendQuery(string extraQuery)
65 | {
66 | ExtraQuery = extraQuery;
67 | return this;
68 | }
69 |
70 | public int Execute(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
71 | {
72 | Parameters.Add(parameters);
73 | return new SqlExecutor(Build()).Execute(connection, commandType, Parameters);
74 | }
75 |
76 | public IEnumerable Query(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
77 | {
78 | Parameters.Add(parameters);
79 | return new SqlExecutor(Build()).Query(connection, commandType, Parameters);
80 | }
81 |
82 | public IEnumerable Query(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
83 | {
84 | Parameters.Add(parameters);
85 | return new SqlExecutor(Build()).Query(connection, commandType, Parameters);
86 | }
87 |
88 | public TColType ExecuteScalar(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
89 | {
90 | Parameters.Add(parameters);
91 | return new SqlExecutor(Build()).ExecuteScalar(connection, commandType, Parameters);
92 | }
93 |
94 | internal void AddParameter(string name, object value)
95 | {
96 | Parameters.Add(name, value);
97 | }
98 | }
99 | }
--------------------------------------------------------------------------------
/Spry/Insert/InsertValue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data;
4 | using System.Linq.Expressions;
5 | using System.Text;
6 |
7 | namespace Spry.Insert
8 | {
9 | public class InsertValue : IExecutable
10 | {
11 | private readonly SpryInsert _spry;
12 | private readonly SpryInsertTable _table;
13 | private readonly SpryParameters _parameters;
14 | private readonly StringBuilder _insertColumnBuilder;
15 | private readonly StringBuilder _insertValueBuilder;
16 | private string _outputCol = null;
17 | private bool _outputIdentity = false;
18 |
19 | internal InsertValue(SpryInsert spry, SpryInsertTable table)
20 | {
21 | _spry = spry;
22 | _table = table;
23 | _insertColumnBuilder = new StringBuilder();
24 | _insertValueBuilder = new StringBuilder();
25 | _parameters = table.Parameters;
26 | }
27 |
28 | public InsertValue Value(Expression> valueExpression)
29 | {
30 | var columnName = SpryExpression.GetColumnName(valueExpression);
31 | var value = SpryExpression.GetColumnValue(valueExpression);
32 | InsertValueImpl(columnName, value);
33 | return this;
34 | }
35 |
36 | public InsertValue Value(string columnName, object value)
37 | {
38 | InsertValueImpl(columnName, value);
39 | return this;
40 | }
41 |
42 | public InsertValue OutputInserted(string outputColumnName)
43 | {
44 | _outputCol = outputColumnName;
45 | return this;
46 | }
47 |
48 | public InsertValue OutputInserted(Expression> columnExpression)
49 | {
50 | _outputCol = SpryExpression.GetColumnName(columnExpression);
51 | return this;
52 | }
53 |
54 | public InsertValue OutputIdentity()
55 | {
56 | _outputIdentity = true;
57 | return this;
58 | }
59 |
60 | private void InsertValueImpl(string columnName, object value)
61 | {
62 | _parameters.Add(columnName, value);
63 | _insertColumnBuilder.Append(columnName + ", ");
64 | _insertValueBuilder.Append("@" + columnName + ", ");
65 | }
66 |
67 | public string Build()
68 | {
69 | return _spry.Build();
70 | }
71 |
72 |
73 |
74 | internal string BuildImpl()
75 | {
76 | RemoveTrailingCommas();
77 |
78 | if (!string.IsNullOrWhiteSpace(_outputCol))
79 | {
80 | return string.Format(@"({0}){1}OUTPUT Inserted.{3}{1}VALUES{1}({2})", _insertColumnBuilder, Environment.NewLine, _insertValueBuilder, _outputCol);
81 | }
82 |
83 | string returnValue = string.Format(@"({0}){1}VALUES{1}({2})", _insertColumnBuilder, Environment.NewLine, _insertValueBuilder);
84 |
85 | if (_outputIdentity)
86 | {
87 | returnValue += @"; SELECT SCOPE_IDENTITY() AS [Inserted];";
88 | }
89 |
90 | return returnValue;
91 | }
92 |
93 | private void RemoveTrailingCommas()
94 | {
95 | _insertColumnBuilder.Length -= 2;
96 | _insertValueBuilder.Length -= 2;
97 | }
98 |
99 | public int Execute(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
100 | {
101 | return _table.Execute(connection, parameters: parameters);
102 | }
103 |
104 | public IEnumerable Query(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
105 | {
106 | return _table.Query(connection, parameters: parameters);
107 | }
108 |
109 | public IEnumerable Query(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
110 | {
111 | return _table.Query(connection, parameters: parameters);
112 | }
113 |
114 | public TColType ExecuteScalar(IDbConnection connection, CommandType commandType = CommandType.Text, SpryParameters parameters = null)
115 | {
116 | return _table.ExecuteScalar(connection, parameters: parameters);
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | Spry - a simple CRUD query builder extension for Dapper
2 | =======================================================
3 |
4 | [](https://dev.azure.com/vigneshmsft/Spry/_build/latest?definitionId=3)
5 |
6 | What is Spry
7 | ------------
8 | [Spry](https://www.nuget.org/packages/Spry) is a simple .NET library which allows you to write fluent CRUD queries
9 | and execute the queries using [Dapper](https://github.com/StackExchange/dapper-dot-net).
10 |
11 | Why Spry ?
12 | ----------
13 | In one of my projects we decided not to write stored procedures
14 | and keep the queries within code, similar to the popular approach being followed by StackOverflow.
15 | The upside of this approach is that one tends to keep only specific CRUD logic in queries and
16 | helps to ensure business logics do not get inside your stored procedures.
17 | It is also easier to debug this way when one sees the actual query being executed on the server.
18 | We also decided not to use any ORM like Entity Framework or NHibernate and only use Dapper.
19 | You start to see code like this.
20 |
21 | ```csharp
22 | public bool InsertCustomer(CustomerDto newCustomer){
23 |
24 | const string insertCustomerQuery = @"INSERT INTO dbo.Customer
25 | ([CustomerId],[Name],[PhoneNumber])
26 | VALUES
27 | (@customerId, @name, @phoneNumber)";
28 |
29 | var count = _connection.Execute(insertCustomerQuery, new { @customerId = newCustomer.CustomerId,
30 | @name= newCustomer.Name,
31 | @phoneNumber = newCustomer.PhoneNumber});
32 |
33 | return count == 1;
34 | }
35 | ```
36 |
37 | This is a relatively straightforward code but beings to break once you start making changes to the `Customer` table.
38 | Believe me changes to the tables are very commom, especially when a project is in its nascent stages.
39 | The moment you decide to rename few columns or add new columns you need to remember to do a find and replace all occurances of
40 | those strings in your solution, which is not a very efficient way of doing things.
41 | This is precisely why most people decide to use an ORM and let if handle all these hassles for you.
42 | But what if you don't want to use a ORM and at the same time not have this problem ?
43 |
44 | What can Spry do ?
45 | -------------------
46 | Simple Insert
47 | ```csharp
48 | var customerInserted = Spry.InsertInto(CUSTOMER_TABLE)
49 | .Value(_ => customer.CustomerId)
50 | .Value(_ => customer.Name)
51 | .Value(_ => customer.DateOfBirth)
52 | .ExecuteScalar(connection) > 0;
53 | ```
54 | Insert and output inserted identity
55 | ```chsarp
56 | customer.CustomerId = Spry.InsertInto(CUSTOMER_TABLE)
57 | .Value(_ => customer.Name)
58 | .Value(_ => customer.DateOfBirth)
59 | .OutputInserted(_ => customer.CustomerId) // or .OutputIdentity()
60 | .ExecuteScalar(connection);
61 | ```
62 | Simple Select
63 | ```csharp
64 | return Spry.Select