記開發我的圖書收藏清單小程序開發(六)Web開發

 

Web頁面開發暫時是沒有問題了,如今開始接上Ptager.BL的DB部分。html

首先須要初始化用戶和書房信息。由於尚未給其餘多餘的設計,因此暫時只有我的暱稱和書房名稱。sql

添加 Init Razor Pages(/Pages/Shelves/Init) 。json

/Pages/Shelves/Init.cshtmlapp

 1 @page  2 @model InitModel  3 @{  4     ViewData["Title"] = "Shelf Init";  5 }  6 
 7 <nav aria-label="breadcrumb">
 8     <ol class="breadcrumb">
 9         <li class="breadcrumb-item"><a asp-page="/Index">Home</a></li>
10         <li class="breadcrumb-item"><a asp-page="/My Books/Index">My Books</a></li>
11         <li class="breadcrumb-item active" aria-current="page">Bookcase Init</li>
12     </ol>
13 </nav>
14 
15 
16 <form method="post">
17     <div class="form-group form-group-lg">
18         <label asp-for="Input.NickName"></label>
19         <input class="form-control form-control-lg" asp-for="Input.NickName" autocomplete="off">
20     </div>
21     <div class="form-group form-group-lg">
22         <label asp-for="Input.ShelfName"></label>
23         <input class="form-control form-control-lg" asp-for="Input.ShelfName" autocomplete="off">
24     </div>
25     <div class="form-group text-right">
26         <button class="btn btn-warning btn-lg" type="submit">Save</button>
27     </div>
28 </form>

 

如今去實現底層Repo的部分。 async

須要在BL層添加基本的底層代碼:post

在PTager.BL.Core層增長DataContract、Models和Repos Interface。性能

暫時尚未用到查詢,因此只須要增長Init Model和Repo Interface就好。優化

新增Shelf.InitSpec Model文件:this

Shelf.InitSpec.csspa

 1 namespace PTager.BL  2 {  3     public partial class Shelf  4  {  5         public class InitSpec  6  {  7             public string NickName { get; set; }  8             public string ShelfName { get; set; }  9  } 10  } 11 }

 

Install Package Newtonsoft.Json

新增_module擴展文件:

_module.cs

1 namespace PTager.BL 2 { 3  [System.Diagnostics.DebuggerNonUserCode] 4     public static partial class extOC 5  { 6         public static string ToJson<T>(this T me) where T : class
7             => JsonConvert.SerializeObject(me); 8  } 9 }

而且引用Projects:Ptager.BL

新增IShelfRepo:

IShelfRepo.cs

 1 using System.Threading.Tasks;  2 
 3 namespace PTager.BL  4 {  5     using M = Shelf;  6     public interface IShelfRepo  7  {  8  Task Init(M.InitSpec spec);  9  } 10 }

 

在PTager.BL.Data層增長Store和Repos的實現。

引用Projects:Ptager.BL和PTager.BL.Core,而且添加Nuget Package:System.Data.SqlClient、Microsoft.EntityFrameworkCore.Relational

其中Store的內容是模仿Linq to SQL的分層作的,但沒那麼高的性能,勉強夠用而已。

RepoBase.cs

 1 namespace PTager.BL.Data  2 {  3     public class RepoBase  4  {  5         protected readonly BLDbContext _context;  6         public RepoBase(BLDbContext context)  7  {  8             _context = context;  9  } 10  } 11 }

_module.cs

1 namespace PTager.BL.Data 2 { 3  [System.Diagnostics.DebuggerNonUserCode] 4     public static partial class extBL { } 5 }

BLDbContext.cs

 1 using System.Threading.Tasks;  2 
 3 namespace PTager.BL.Data.Store  4 {  5     public class BLDbContext : DbContext  6  {  7         public BLDbContext(DbContextOptions<BLDbContext> options)  8         : base(options)  9  { 10             this.ChangeTracker.AutoDetectChangesEnabled = false; 11  } 12 
13         #region { Functions }
14         
15         #endregion
16 
17         #region { Actions }
18 
19         public async Task Shelf_Init(string json) 20             => await this.ExecuteMethodCallAsync(nameof(Shelf_Init), args: json); 21         
22         #endregion
23  } 24 }

BLDbContext.ext.cs(這是目前代碼中最髒的部分了,找時間須要優化這個部分)

 1 using Microsoft.EntityFrameworkCore;  2 using System;  3 using System.Data;  4 using System.Data.SqlClient;  5 using System.Linq;  6 using System.Reflection;  7 using System.Threading.Tasks;  8 
 9 namespace PTager.BL.Data.Store 10 { 11     public static partial class extUSDContext 12  { 13         public static IQueryable<T> CreateMethodCallQuery<T>(this DbContext me, MethodBase method, string schema = "svc") 14             where T : class
15             => me.CreateMethodCallQuery<T>(method, schema, null); 16         public static IQueryable<T> CreateMethodCallQuery<T>(this DbContext me, MethodBase method, string schema = "svc", params object[] args) 17             where T : class
18  { 19             var hasArgs = args != null && args.Length > 0; 20             //var fields = typeof(T).GetType().ToSelectFields();
21             var sql = $"select * from {schema}.{method.Name.Replace("_", "$")}("; 22             if (hasArgs) sql += string.Join(", ", args.Select(x => $"@p{args.ToList().IndexOf(x)}")); 23             sql += ")"; 24             me.Database.SetCommandTimeout(TimeSpan.FromMinutes(30)); 25             return hasArgs ? me.Set<T>().FromSql(sql, args) : me.Set<T>().FromSql(sql); 26  } 27 
28         public static async Task<string> ExecuteMethodCallAsync(this DbContext me, string methodName) 29             => await me.ExecuteMethodCallAsync(methodName, null); 30         public static async Task<string> ExecuteMethodCallAsync(this DbContext me, string methodName, params object[] args) 31             => await me.ExecuteMethodCallAsync(methodName, false, args); 32         public static async Task<string> ExecuteMethodCallAsync(this DbContext me, string methodName, bool lastOutput, params object[] args) 33  { 34             var hasArgs = args != null && args.Length > 0; 35             var sql = $"svc.{methodName.Replace("_", "$")} "; 36             if (!hasArgs) 37  { 38                 if (lastOutput == false) 39  { 40                     await me.Database.ExecuteSqlCommandAsync(sql); 41                     return string.Empty; 42  } 43  } 44             else
45  { 46                 sql += string.Join(", ", args.Select(x => $"@p{args.ToList().IndexOf(x)}")); 47                 if (lastOutput == false) 48  { 49                     await me.Database.ExecuteSqlCommandAsync(sql, args); 50                     return string.Empty; 51  } 52                 sql += ", "; 53  } 54             sql += " @result output"; 55             var parameters = args.Select(x => new SqlParameter($"@p{args.ToList().IndexOf(x)}", x)).ToList(); 56             var outParam = new SqlParameter("@result", SqlDbType.VarChar, int.MaxValue) 57  { 58                 Value = string.Empty, 59                 Direction = ParameterDirection.Output 60  }; 61  parameters.Add(outParam); 62             me.Database.SetCommandTimeout(TimeSpan.FromMinutes(30)); 63             await me.Database.ExecuteSqlCommandAsync(sql, parameters.ToArray()); 64             return outParam.Value.ToString(); 65  } 66  } 67 }

好了,基礎已建好,新增ShelfRepo的實現。

ShelfRepo.cs

 1 namespace PTager.BL.Data.Repos  2 {  3     using System.Threading.Tasks;  4     using PTager.BL.Data.Store;  5     using M = Shelf;  6     public class ShelfRepo : RepoBase, IShelfRepo  7  {  8         public ShelfRepo(BLDbContext context) : base(context)  9  { 10  } 11 
12         public async Task Init(M.InitSpec spec) 13             => await _context.Shelf_Init(spec.ToJson()); 14  } 15 }

 

在WebUI的Project中,引用新增的三個底層項目,並在Statup.cs的ConfigureServices中註冊IShelfRepo的依賴和BL DB的鏈接註冊:

1     services.AddDbContext<BLDbContext>(options =>
2  options.UseSqlServer( 3             Configuration.GetConnectionString("BLConnection"))); 4     services.AddScoped<IShelfRepo, ShelfRepo>();

 

固然,這個時會報錯的,由於咱們並無在appsetting中添加這個DB Connection。

修改後的appsettings.json

 1 {  2     "ConnectionStrings": {  3         "DefaultConnection": "Server=.\\SQL2017;Database=PTager;Trusted_Connection=True;MultipleActiveResultSets=true",  4         "BLConnection": "Server=.\\SQL2017;Database=PTagerBL;Trusted_Connection=True;MultipleActiveResultSets=true"
 5  },  6   "Logging": {  7     "LogLevel": {  8       "Default": "Warning"
 9  } 10  }, 11   "AllowedHosts": "*"
12 }

 

接下來須要去新建DB的Script實現這個Shelf_Init功能了。

相關文章
相關標籤/搜索