簡介:SqlRepoEx是 .Net平臺下兼容.NET Standard 2.0人一個輕型的ORM。解決了Lambda轉Sql語句這一難題,SqlRepoEx使用的是Lambda表達式,因此,對c#程序員來講,是很是簡單的,其語法特色與Linq to Sql極爲類似。不只實現了完整的Select、Insert、Update、Delete等語句解析器,同時,也實現了Select、where、order by等子句,這些語句與子句均支持導出SQL語句,使得拼接複雜場景SQL語句變得輕鬆,SqlRepoEx很快其原生數據訪問與Dapper不相上下,SqlRepoEx自己支持Sql Server與MySql方言,同時經過SqlRepoEx.Normal支持非方言SQL。SqlRepoEx沒侵入性,僅經過簡單的幾個特性,就能讓類與數據庫關聯起來;git
*本系列以靜態工廠爲例;程序員
*數據來源於Northwind數據庫;github
*完整的代碼見 SqlRepoEx2.2.1 GitHub示例 SqlRepoEx2.2.1 碼雲示例數據庫
可經過下列兩種方式獲取c#
一、工廠獲取app
private static IDbConnection dbConnection = MsSqlRepoFactory.DbConnection;ui
二、數據倉儲this
var repository = MsSqlRepoFactory.Create<AzProducts>();orm
IDbConnection dbConnection = repository.DbConnection;事務
一、SqlRepoEx的Insert、Updata 增長了ParamSql()方法獲取 @ 參數 語句;
二、對於Where條件語句中,如要生成 @ 參數 語句 只須要在表達式中 .Where(p => p.ProductID == p.ProductID);右側表達式中使用類型屬性表達式便可。
三、關於數據字段與屬性聯,將在下篇中介紹
public static void QueryOnly()
{
// 建立數據倉儲
var repository = MsSqlRepoFactory.Create<AzProducts>();
//查詢
var result = repository.Query().Top(10);
Console.WriteLine(result.Sql());
// 經過 Dapper 獲取數據
IEnumerable<AzProducts> azProducts = dbConnection.Query<AzProducts>(result.Sql());
// 顯示結果(只取兩列,僅爲顯示目的)
foreach (var item in azProducts)
{
Console.WriteLine($"{item.ProductID}\t{item.ProductName2}");
}
}
此方法生成的 SQL
SELECT TOP (10) [dbo].[Products].[ProductID]
, [dbo].[Products].[ProductName] as [ProductName2]
, [dbo].[Products].[SupplierID]
, [dbo].[Products].[CategoryID]
, [dbo].[Products].[QuantityPerUnit]
, [dbo].[Products].[UnitPrice]
, [dbo].[Products].[UnitsInStock]
, [dbo].[Products].[UnitsOnOrder]
, [dbo].[Products].[ReorderLevel]
, [dbo].[Products].[Discontinued]
FROM [dbo].[Products];
此方法生成的結果
1 Chai
2 Chang
3 Aniseed Syrup
4 Chef Anton's Cajun Seasoning
5 Chef Anton's Gumbo Mix
6 Grandma's Boysenberry Spread
7 Uncle Bob's Organic Dried Pears
8 Northwoods Cranberry Sauce
9 Mishi Kobe Niku
10 Ikura
* LeftOuterJoin、RightOuterJoin與此例類似
public static void DoInnerJoin()
{
// 建立數據倉儲
var repository = MsSqlRepoFactory.Create<AzProducts>();
// 構建查詢語句,相較而言,語法更接近於SQL,與Linq是有很大區別的
var result = repository.Query()
.InnerJoin<AzSuppliers>()
.On<AzSuppliers>((l, r) => l.SupplierID == r.SupplierID, r => r.CompanyName)
.Top(10);
Console.WriteLine(result.Sql());
Console.WriteLine();
// 經過 Dapper 獲取數據
IEnumerable<AzProducts> azProducts = dbConnection.Query<AzProducts>(result.Sql());
foreach (var item in azProducts)
{
Console.WriteLine($"{item.ProductID}\t{item.ProductName2}\t{item.Supplier}");
}
}
此方法生成的 SQL
SELECT TOP (10) [dbo].[Products].[ProductID]
, [dbo].[Products].[ProductName] as [ProductName2]
, [dbo].[Products].[SupplierID]
, [dbo].[Products].[CategoryID]
, [dbo].[Products].[QuantityPerUnit]
, [dbo].[Products].[UnitPrice]
, [dbo].[Products].[UnitsInStock]
, [dbo].[Products].[UnitsOnOrder]
, [dbo].[Products].[ReorderLevel]
, [dbo].[Products].[Discontinued]
, [dbo].[Suppliers].[CompanyName] as [Supplier]
FROM [dbo].[Products]
INNER JOIN [dbo].[Suppliers]
ON [dbo].[Products].[SupplierID] = [dbo].[Suppliers].[SupplierID];
此方法生成的結果
1 Chai Exotic Liquids
2 Chang Exotic Liquids
3 Aniseed Syrup Exotic Liquids
4 Chef Anton's Cajun Seasoning New Orleans Cajun Delights
5 Chef Anton's Gumbo Mix New Orleans Cajun Delights
6 Grandma's Boysenberry Spread Grandma Kelly's Homestead
7 Uncle Bob's Organic Dried Pears Grandma Kelly's Homestead
8 Northwoods Cranberry Sauce Grandma Kelly's Homestead
9 Mishi Kobe Niku Tokyo Traders
10 Ikura Tokyo Traders
public static void QueryWhere()
{
// 建立數據倉儲
var repository = MsSqlRepoFactory.Create<AzProducts>();
var result = repository.Query()
.Where(p => p.ProductName2.Contains("t") && p.ProductID < 100)
.Top(10);
Console.WriteLine(result.Sql());
Console.WriteLine();
// 經過 Dapper 獲取數據
IEnumerable<AzProducts> azProducts = dbConnection.Query<AzProducts>(result.Sql());
foreach (var item in azProducts)
{
Console.WriteLine($"{item.ProductID}\t{item.ProductName2}");
}
}
此方法生成的 SQL
SELECT TOP (10) [dbo].[Products].[ProductID]
, [dbo].[Products].[ProductName] as [ProductName2]
, [dbo].[Products].[SupplierID]
, [dbo].[Products].[CategoryID]
, [dbo].[Products].[QuantityPerUnit]
, [dbo].[Products].[UnitPrice]
, [dbo].[Products].[UnitsInStock]
, [dbo].[Products].[UnitsOnOrder]
, [dbo].[Products].[ReorderLevel]
, [dbo].[Products].[Discontinued]
FROM [dbo].[Products]
WHERE ((([dbo].[Products].[ProductName] LIKE '%t%') and ([dbo].[Products].[ProductID] < 100)));
此方法生成的結果
4 Chef Anton's Cajun Seasoning
5 Chef Anton's Gumbo Mix
8 Northwoods Cranberry Sauce
12 Queso Manchego La Pastora
14 Tofu
17 Alice Mutton
18 Carnarvon Tigers
19 Teatime Chocolate Biscuits
22 Gustaf's Kn?ckebr?d
23 Tunnbr?d
public static void QueryUnion()
{
// 建立數據倉儲
var repository = MsSqlRepoFactory.Create<AzCustomers>();
// 此語句不會參與數據查詢,只是做爲Union的包裹
// 若是此語句自己也是數據查詢,請增長到new List<UnionSql>中
var result = repository.Query()
.Select(c => c.CustomerID, c => c.CompanyName);
var result01 = repository.Query()
.Select(c => c.CustomerID, c => c.CompanyName)
.Where(c => c.CustomerID == "ANATR");
var result02 = repository.Query()
.Select(c => c.CustomerID, c => c.CompanyName)
.Where(c => c.CustomerID == "FRANK");
var result03 = repository.Query()
.Select(c => c.CustomerID, c => c.CompanyName)
.Where(c => c.CustomerID == "TRADH");
var resultAllSql = result.UnionSql(new List<UnionSql> {
UnionSql.New( result01,UnionType.Union ),
UnionSql.New( result02,UnionType.Union ),
UnionSql.New( result03,UnionType.Union ), });
Console.WriteLine(resultAllSql);
Console.WriteLine();
// 經過 Dapper 獲取數據
IEnumerable<AzCustomers> azCustomers = dbConnection.Query<AzCustomers>(resultAllSql);
foreach (var item in azCustomers)
{
Console.WriteLine($"{item.CustomerID}\t{item.CompanyName}");
}
}
此方法生成的 SQL
SELECT [_this_is_union].[CustomerID]
, [_this_is_union].[CompanyName]
FROM ( SELECT [dbo].[Customers].[CustomerID]
, [dbo].[Customers].[CompanyName]
FROM [dbo].[Customers]
WHERE (([dbo].[Customers].[CustomerID] = 'ANATR'))
UNION
SELECT [dbo].[Customers].[CustomerID]
, [dbo].[Customers].[CompanyName]
FROM [dbo].[Customers]
WHERE (([dbo].[Customers].[CustomerID] = 'FRANK'))
UNION
SELECT [dbo].[Customers].[CustomerID]
, [dbo].[Customers].[CompanyName]
FROM [dbo].[Customers]
WHERE (([dbo].[Customers].[CustomerID] = 'TRADH')) )
AS _this_is_union
此方法生成的結果
ANATR Ana Trujillo Emparedados y helados
FRANK Frankenversand
TRADH Tradi??o Hipermercados
public static void DoInsertEntityParam()
{
var repository = MsSqlRepoFactory.Create<AzProducts>();
AzProducts azProduct = new AzProducts { ProductName2 = "testvalue" };
var resultinsert = repository
.Insert();
// 使用ParamSql()方法獲取 @ 參數SQL語句
Console.WriteLine(resultinsert.ParamSql());
Console.WriteLine();
// 需返回自增字段,因此用Query
IEnumerable<AzProducts> azProducts = dbConnection.Query<AzProducts>(resultinsert.ParamSql(), azProduct);
foreach (var item in azProducts)
{
Console.WriteLine($"{item.ProductID}\t{item.ProductName2}");
}
}
此方法生成的 SQL
INSERT [dbo].[Products]([ProductName],[SupplierID],[CategoryID],[QuantityPerUnit],[UnitPrice],[UnitsInStock],[UnitsOnOrder],[ReorderLevel],[Discontinued])
VALUES(@ProductName2,@SupplierID,@CategoryID,@QuantityPerUnit,@UnitPrice,@UnitsInStock,@UnitsOnOrder,@ReorderLevel,@Discontinued);
SELECT [ProductID],[ProductName] as ProductName2,[SupplierID],[CategoryID],[QuantityPerUnit],[UnitPrice],[UnitsInStock],[UnitsOnOrder],[ReorderLevel],[Discontinued]
FROM [dbo].[Products]
WHERE [ProductID] = SCOPE_IDENTITY();
此方法生成的結果
96 testvalue
public static void DoInsertEntityParamBatch()
{
// 建立數據倉儲
var repository = MsSqlRepoFactory.Create<AzProducts>();
// 設置要批處理的數據
List<AzProducts> azProductList = new List<AzProducts>{
new AzProducts { ProductName2 = "testvalue1" ,CategoryID=1,UnitPrice=123},
new AzProducts { ProductName2 = "testvalue2" ,CategoryID=1,UnitPrice=123},
new AzProducts { ProductName2 = "testvalue3" ,CategoryID=1,UnitPrice=123},
new AzProducts { ProductName2 = "testvalue4" ,CategoryID=1,UnitPrice=123 },
new AzProducts { ProductName2 = "testvalue5" ,CategoryID=1,UnitPrice=123},
new AzProducts { ProductName2 = "testvalue6" ,CategoryID=1,UnitPrice=123},
};
// 使用選擇增長
var resultinsert = repository
.Insert().ParamWith(c => c.ProductName2, c => c.UnitPrice, c => c.CategoryID);
Console.WriteLine(resultinsert.ParamSql());
Console.WriteLine();
// 經過 Dapper 批處理
dbConnection.Execute(resultinsert.ParamSql(), azProductList);
}
此方法生成的 SQL
INSERT [dbo].[Products]([ProductName],[UnitPrice],[CategoryID])
VALUES(@ProductName2,@UnitPrice,@CategoryID);
SELECT [ProductName] as ProductName2,[UnitPrice],[CategoryID],[ProductID]
FROM [dbo].[Products]
WHERE [ProductID] = SCOPE_IDENTITY();
public static void DoUpdateEntityParam()
{
// 建立數據倉儲
var repository = MsSqlRepoFactory.Create<AzProducts>();
// 構建更新語句
var resultUpdate = repository
.Update()
.ParamSet(p => p.ProductName2, p => p.CategoryID)
// Where 中使用下列格式語句,可生成帶 @ 的參數
.Where(p => p.ProductID == p.ProductID);
Console.WriteLine(resultUpdate.ParamSql());
Console.WriteLine();
// 需更新的數據
AzProducts products = new AzProducts() { ProductID = 84, ProductName2 = "testvalue100", CategoryID = 7 };
// 經過 Dapper 更新數據
int result = dbConnection.Execute(resultUpdate.ParamSql(), products);
Console.WriteLine($"{result}");
}
此方法生成的 SQL
UPDATE [dbo].[Products]
SET ProductName = @ProductName2, CategoryID = @CategoryID
WHERE (([dbo].[Products].[ProductID] = @ProductID));
public static void DoDeleteEntity(bool go = false)
{
// 建立數據倉儲
var repository = MsSqlRepoFactory.Create<AzProducts>();
// 要刪除的數據
AzProducts azProducts = new AzProducts { ProductName2 = "testvalue", ProductID = 81 };
// 構建刪除,使用實例構建時,若是不設置 Where 語句
// SqlRepoEx 會以關鍵詞來構建 Where 語句
var resultUpdate = repository.Delete().For(azProducts);
Console.WriteLine(resultUpdate.Sql());
Console.WriteLine();
// 經過 Dapper 刪除數據
int result = dbConnection.Execute(resultUpdate.Sql());
Console.WriteLine($"{result}");
}
此方法生成的 SQL
DELETE [dbo].[Products]
WHERE (([dbo].[Products].[ProductID] = @ProductID));
public static void DoDeleteTransaction()
{
// 建立數據倉儲
var repository = MsSqlRepoFactory.Create<AzProducts>();
// 構建刪除,若是不是實例構建,用戶必需自行指定刪除條件
// Where 中使用下列格式語句,可生成帶 @ 的參數
var resultUpdate = repository.Delete().Where(p => p.ProductID == p.ProductID);
// 要刪除的數據集
List<AzProducts> azProductList = new List<AzProducts>
{
new AzProducts{ProductID=92},
new AzProducts{ProductID=93},
new AzProducts{ProductID=94},
new AzProducts{ProductID=91},
};
Console.WriteLine(resultUpdate.Sql());
Console.WriteLine();
// 使用事務控制
using (var transaction = dbConnection.BeginTransaction())
{
// 經過 Dapper 刪除,同時指定了事務
dbConnection.Execute(resultUpdate.Sql(), azProductList, transaction: transaction);
// 僅爲了演示,此處回滾事務,取消刪除
// 若是相要提交事務,請將此處改成 transaction.Commit() 可看到刪除效果
transaction.Rollback();
}
}
此方法生成的 SQL
DELETE [dbo].[Products]
WHERE (([dbo].[Products].[ProductID] = @ProductID));