diff --git a/README.md b/README.md index c40120c..be500a4 100644 --- a/README.md +++ b/README.md @@ -56,36 +56,29 @@ NuGet\Install-Package Ecnu.OpenApi.Sdk -Version 1.0.0 ``` 安装完成后,进行简单配置即可获得授权接口的数据。以下为简单示例 -* 注意:开发者需要根据所需要数据的接口来编写实体类(如示例代码中的FakeData类需要根据fake或fakewithts接口数据自己编写) +* 注意:开发者需要根据所需要数据的接口来编写实体类(如示例代码中的FakeData类需要根据fakewithts接口数据自己编写) ```csharp static void Main(string[] args) { //获取token所需要的配置 - OauthConfig.ClientId = "yourid"; - OauthConfig.ClientSecret = "yoursecret"; + OAuth2Config.ClientId = "yourid"; + OAuth2Config.ClientSecret = "yoursecret"; //初始化token - OauthToken.InitialOauthCredential(OauthConfig.ClientId, OauthConfig.ClientSecret); + SdkApi.InitOAuth2ClientCredentials(OAuth2Config.ClientId, OAuth2Config.ClientSecret); //api配置 - ApiConfig.ApiUrl = "/api/v1/sync/fakewithts"; - ApiConfig.OutputFilePath = @"D:\newsync.csv"; - ApiConfig.PageSize = 2000; - ApiConfig.BatchSize = 10000; - SdkApi.AddParameter("ts", "0"); + APIConfig.ApiUrl = "/api/v1/sync/fakewithts"; + APIConfig.PageSize = 10; + APIConfig.ApiParameters.Add("ts", "0"); - - //初始化ouath,获取token - OauthToken.InitialOauthCredential(OauthConfig.ClientId, OauthConfig.ClientSecret); - - - //调用api,获取数据 - var res = SdkApi.CallApi("https://api.ecnu.edu.cn/api/v1/sync/fakewithts?pageSize=100&pageNum=1&ts=0", "get"); - Console.WriteLine(res); - Console.ReadLine(); + //导入模型,可以根据业务再进行筛查 + List list = SdkApi.SyncToModel(); + var result = list.Where(x=> x.colInt1 > 30).ToList(); } ``` 详细用法请参考示例: +- [CallAPI](examples/exampleCallAPI.cs) - [SyncToCSV](examples/exampleToCsv.cs) - [SyncToModel](examples/exampleToModel.cs) - [SyncToDB](examples/exampleToDb.cs) diff --git a/ecnu-openapi-sdk-csharp.csproj b/ecnu-openapi-sdk-csharp.csproj index 122ee83..122763c 100644 --- a/ecnu-openapi-sdk-csharp.csproj +++ b/ecnu-openapi-sdk-csharp.csproj @@ -8,8 +8,13 @@ ECNU ECNU Ecnu.OpenApi.Sdk - readme.md + README.md 提供接入ECNU数据开发帮助,开发者仅需简单的配置即可获得ECNU授权的数据。 + https://github.com/ECNU/ecnu-openapi-sdk-csharp + 1.0.2 + 1.0.2 + 1.0.2 + 提供接入ECNU数据开发帮助,开发者仅需简单的配置即可获得ECNU授权的数据。 diff --git a/examples/exampleCallAPI.cs b/examples/exampleCallAPI.cs new file mode 100644 index 0000000..64bb518 --- /dev/null +++ b/examples/exampleCallAPI.cs @@ -0,0 +1,20 @@ +using DataSyncSdk; + +namespace ecnu_openapi_sdk_csharp.examples +{ + public class exampleCallAPI + { + static void Main(string[] args) + { + //获取token所需要的配置 + OAuth2Config.ClientId = "yourid"; + OAuth2Config.ClientSecret = "yoursecret"; + //初始化token + SdkApi.InitOAuth2ClientCredentials(OAuth2Config.ClientId, OAuth2Config.ClientSecret); + + //调用api,获取数据 + var res = SdkApi.CallApi("https://api.ecnu.edu.cn/api/v1/sync/fakewithts?ts=0&pageNum=1&pageSize=1", "get"); + Console.WriteLine(res); + } + } +} diff --git a/examples/examplePerformance.cs b/examples/examplePerformance.cs index c7b2e61..2a935aa 100644 --- a/examples/examplePerformance.cs +++ b/examples/examplePerformance.cs @@ -4,51 +4,51 @@ public class examplePerformance { static void Main(string[] args) { - //获取token所需要的配置 - OauthConfig.ClientId = "yourid"; - OauthConfig.ClientSecret = "yoursecret"; - //初始化token - OauthToken.InitialOauthCredential(OauthConfig.ClientId, OauthConfig.ClientSecret); + //获取token所需要的配置 + OAuth2Config.ClientId = "yourid"; + OAuth2Config.ClientSecret = "yoursecret"; + //初始化token + SdkApi.InitOAuth2ClientCredentials(OAuth2Config.ClientId, OAuth2Config.ClientSecret); - //api配置 - ApiConfig.ApiUrl = "/api/v1/sync/fake"; - ApiConfig.OutputFilePath = @"D:\newsync.csv"; - ApiConfig.PageSize = 2000; - ApiConfig.BatchSize = 10000; - SdkApi.AddParameter("totalNum", "1000000"); + //api配置 + APIConfig.ApiUrl = "/api/v1/sync/fake"; + APIConfig.OutputFilePath = @"D:\newsync.csv"; + APIConfig.PageSize = 2000; + APIConfig.BatchSize = 10000; + APIConfig.ApiParameters.Add("totalNum", "1000000"); - //同步至模型 - Stopwatch st = new Stopwatch(); - st.Start(); - GC.Collect(); - var list = SdkApi.SyncToModel(); - double usedMemory = Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0; - st.Stop(); - Console.WriteLine("消耗内存:" + usedMemory + "MB"); - Console.WriteLine("程序执行耗时:" + st.ElapsedMilliseconds / 1000 + "S"); + //同步至模型 + Stopwatch st = new Stopwatch(); + st.Start(); + GC.Collect(); + var list = SdkApi.SyncToModel(); + double usedMemory = Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0; + st.Stop(); + Console.WriteLine("消耗内存:" + usedMemory + "MB"); + Console.WriteLine("程序执行耗时:" + st.ElapsedMilliseconds / 1000 + "S"); - //同步至csv文件 - st.Start(); - GC.Collect(); - SdkApi.SyncToCsv(ApiConfig.OutputFilePath); - usedMemory = Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0; - st.Stop(); - Console.WriteLine("消耗内存:" + usedMemory + "MB"); - Console.WriteLine("程序执行耗时:" + st.ElapsedMilliseconds / 1000 + "S"); - Console.ReadLine(); + //同步至csv文件 + st.Start(); + GC.Collect(); + SdkApi.SyncToCsv(APIConfig.OutputFilePath); + usedMemory = Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0; + st.Stop(); + Console.WriteLine("消耗内存:" + usedMemory + "MB"); + Console.WriteLine("程序执行耗时:" + st.ElapsedMilliseconds / 1000 + "S"); + Console.ReadLine(); - //同步至数据库,数据库类型及链接字符串在SqlSugarDbContext类中配置 - st.Start(); - GC.Collect(); - string conStr = "DataSource=D:\\syncdb.db"; - SqlSugarDbContext db = new SqlSugarDbContext(conStr, SqlSugar.DbType.Sqlite); - SdkApi.SyncToDb(db); - usedMemory = Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0; - st.Stop(); - Console.WriteLine("消耗内存:" + usedMemory + "MB"); - Console.WriteLine("程序执行耗时:" + st.ElapsedMilliseconds / 1000 + "S"); - Console.ReadLine(); + //同步至数据库,数据库类型及链接字符串在SqlSugarDbContext类中配置 + st.Start(); + GC.Collect(); + string conStr = "DataSource=D:\\syncdb.db"; + SqlSugarDbContext db = new SqlSugarDbContext(conStr, SqlSugar.DbType.Sqlite); + SdkApi.SyncToDb(db); + usedMemory = Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0; + st.Stop(); + Console.WriteLine("消耗内存:" + usedMemory + "MB"); + Console.WriteLine("程序执行耗时:" + st.ElapsedMilliseconds / 1000 + "S"); + Console.ReadLine(); } } \ No newline at end of file diff --git a/examples/exampleToCsv.cs b/examples/exampleToCsv.cs index 24bd3e7..829e319 100644 --- a/examples/exampleToCsv.cs +++ b/examples/exampleToCsv.cs @@ -4,19 +4,19 @@ public class exampleToCsv static void Main(string[] args) { //获取token所需要的配置 - OauthConfig.ClientId = "yourid"; - OauthConfig.ClientSecret = "yoursecret"; + OAuth2Config.ClientId = "yourid"; + OAuth2Config.ClientSecret = "yoursecret"; //初始化token - OauthToken.InitialOauthCredential(OauthConfig.ClientId, OauthConfig.ClientSecret); + SdkApi.InitOAuth2ClientCredentials(OAuth2Config.ClientId, OAuth2Config.ClientSecret); //api配置 - ApiConfig.ApiUrl = "/api/v1/sync/fakewithts"; - ApiConfig.OutputFilePath = @"D:\newsync.csv"; - ApiConfig.PageSize = 10; - ApiConfig.ApiParameters.Add("ts", "0"); + APIConfig.ApiUrl = "/api/v1/sync/fakewithts"; + APIConfig.OutputFilePath = @"D:\newsync.csv"; + APIConfig.PageSize = 10; + APIConfig.ApiParameters.Add("ts", "0"); //写入csv文件 - SdkApi.SyncToCsv(ApiConfig.OutputFilePath); + SdkApi.SyncToCsv(APIConfig.OutputFilePath); } } \ No newline at end of file diff --git a/examples/exampleToDb.cs b/examples/exampleToDb.cs index dc71cb3..57c4b61 100644 --- a/examples/exampleToDb.cs +++ b/examples/exampleToDb.cs @@ -4,16 +4,16 @@ public class exampleToDb static void Main(string[] args) { //获取token所需要的配置 - OauthConfig.ClientId = "yourid"; - OauthConfig.ClientSecret = "yoursecret"; + OAuth2Config.ClientId = "yourid"; + OAuth2Config.ClientSecret = "yoursecret"; //初始化token - OauthToken.InitialOauthCredential(OauthConfig.ClientId, OauthConfig.ClientSecret); + SdkApi.InitOAuth2ClientCredentials(OAuth2Config.ClientId, OAuth2Config.ClientSecret); //api配置 - ApiConfig.ApiUrl = "/api/v1/sync/fakewithts"; - ApiConfig.PageSize = 10; - ApiConfig.ApiParameters.Add("ts", "0"); + APIConfig.ApiUrl = "/api/v1/sync/fakewithts"; + APIConfig.PageSize = 10; + APIConfig.ApiParameters.Add("ts", "0"); /* "SqlServer": "Server = yourserver; Initial Catalog = yourdb; UID = youruser; PWD = yourpwd", diff --git a/examples/exampleToModel.cs b/examples/exampleToModel.cs index 7c11109..911e235 100644 --- a/examples/exampleToModel.cs +++ b/examples/exampleToModel.cs @@ -3,17 +3,17 @@ public class exampleToModel { static void Main(string[] args) { - //获取token所需要的配置 - OauthConfig.ClientId = "yourid"; - OauthConfig.ClientSecret = "yoursecret"; + //获取token所需要的配置 + OAuth2Config.ClientId = "yourid"; + OAuth2Config.ClientSecret = "yoursecret"; //初始化token - OauthToken.InitialOauthCredential(OauthConfig.ClientId, OauthConfig.ClientSecret); + SdkApi.InitOAuth2ClientCredentials(OAuth2Config.ClientId, OAuth2Config.ClientSecret); //api配置 - ApiConfig.ApiUrl = "/api/v1/sync/fakewithts"; - ApiConfig.PageSize = 10; - ApiConfig.ApiParameters.Add("ts", "0"); + APIConfig.ApiUrl = "/api/v1/sync/fakewithts"; + APIConfig.PageSize = 10; + APIConfig.ApiParameters.Add("ts", "0"); //导入模型,可以根据业务再进行筛查 List list = SdkApi.SyncToModel(); diff --git a/src/ConfigClass.cs b/src/ConfigClass.cs index 8799016..ab5d2cd 100644 --- a/src/ConfigClass.cs +++ b/src/ConfigClass.cs @@ -4,17 +4,17 @@ namespace DataSyncSdk { - public static class OauthConfig + public static class OAuth2Config { public static string ClientId { get; set; } - public static string ClientSecret { get; set;} + public static string ClientSecret { get; set; } public static string DefaultScope { get; set; } = "ECNU"; public static int DefaultTimeOut { get; set; } = 10; } - public static class ApiConfig + public static class APIConfig { public static string DefaultBaseUrl { get; set; } = "https://api.ecnu.edu.cn"; - public static string OutputFilePath { get; set; } = "D:\\syncresult.csv"; + public static string OutputFilePath { get; set; } = "syncresult.csv"; public static string ApiUrl; /// /// 取api数据时每页取的数据量,默认2000 @@ -26,7 +26,7 @@ public static class ApiConfig /// 建议最大不超过100000,且设置为PageSize的整数倍 /// public static int BatchSize { get; set; } = 10000; - public static Dictionary ApiParameters { get; set; } + public static Dictionary ApiParameters { get; set; } = new Dictionary(); } diff --git a/src/HttpHelper.cs b/src/HttpHelper.cs index 516f3c9..6221597 100644 --- a/src/HttpHelper.cs +++ b/src/HttpHelper.cs @@ -13,12 +13,12 @@ public static string HttpGetAsync(string url) { string retString = string.Empty; - if (!string.IsNullOrEmpty(OauthToken.token)) + if (!string.IsNullOrEmpty(SdkApi.token)) { using (HttpClient httpClient = new HttpClient()) { - httpClient.Timeout = TimeSpan.FromSeconds(OauthConfig.DefaultTimeOut); - httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + OauthToken.token); + httpClient.Timeout = TimeSpan.FromSeconds(OAuth2Config.DefaultTimeOut); + httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + SdkApi.token); var response = httpClient.GetAsync(url).Result; if (!response.IsSuccessStatusCode) { @@ -38,7 +38,7 @@ public static string HttpGetAsync(string url) { if (retry++ >= 3) return ""; - OauthToken.InitialOauthCredential(OauthConfig.ClientId, OauthConfig.ClientSecret); + SdkApi.InitOAuth2ClientCredentials(OAuth2Config.ClientId, OAuth2Config.ClientSecret); HttpGetAsync(url); } return retString; diff --git a/src/OauthToken.cs b/src/OauthToken.cs deleted file mode 100644 index 1f1f6a7..0000000 --- a/src/OauthToken.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Net.Http; - -namespace DataSyncSdk -{ - public class OauthToken - { - public static string token = string.Empty; - private static long expireTimeStamp = 0; - - /// - /// 初始化Oauth,获取token - /// - /// - /// - public static void InitialOauthCredential(string clientId, string clientSecret) - { - if (!string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(clientSecret)) - { - if (token == string.Empty && expireTimeStamp == 0) - { - GetTokenAsync(clientId, clientSecret); - } - else if (expireTimeStamp - long.Parse(GetTimeStamp()) <= 600) - { - GetTokenAsync(clientId, clientSecret); - } - } - else - { - Console.WriteLine("config oauth client"); - return; - } - } - - - /// - /// 获取oauth token - /// - /// - /// - /// - private static void GetTokenAsync(string clientId, string clientSecret) - { - try - { - using (var httpClient = new HttpClient()) - { - httpClient.Timeout = TimeSpan.FromSeconds(OauthConfig.DefaultTimeOut); - var url = ApiConfig.DefaultBaseUrl + "/oauth2/token"; - var response = httpClient.PostAsync(url, new FormUrlEncodedContent(new List>() - { - new KeyValuePair("grant_type","client_credentials"), - new KeyValuePair("client_id",clientId), - new KeyValuePair("client_secret", clientSecret), - })).Result; - var str = response.Content.ReadAsStringAsync().Result; - var res = JObject.Parse(str); - expireTimeStamp = long.Parse(GetTimeStamp()) + 7200; - token = res["access_token"].ToString(); - Console.WriteLine(token + " expire:" + expireTimeStamp + " now:" + GetTimeStamp()); - } - } - catch (Exception ex) - { - throw ex; - } - } - - - public static string GetTimeStamp() - { - TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0); - return Convert.ToInt64(ts.TotalSeconds).ToString(); - } - } -} diff --git a/src/SdkApi.cs b/src/SdkApi.cs index 1ce39c9..b5da6f4 100644 --- a/src/SdkApi.cs +++ b/src/SdkApi.cs @@ -1,19 +1,83 @@ using CsvHelper; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; namespace DataSyncSdk { public class SdkApi { - public static void SyncToDb() + #region token 管理 + public static string token = string.Empty; + private static long expireTimeStamp = 0; + + /// + /// 初始化Oauth,获取token + /// + /// + /// + public static void InitOAuth2ClientCredentials(string clientId, string clientSecret) { + if (!string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(clientSecret)) + { + if (token == string.Empty && expireTimeStamp == 0) + { + GetTokenAsync(clientId, clientSecret); + } + else if (expireTimeStamp - long.Parse(GetTimeStamp()) <= 600) + { + GetTokenAsync(clientId, clientSecret); + } + } + else + { + Console.WriteLine("config oauth client"); + return; + } + } + + /// + /// 获取oauth token + /// + /// + /// + /// + private static void GetTokenAsync(string clientId, string clientSecret) + { + try + { + using (var httpClient = new HttpClient()) + { + httpClient.Timeout = TimeSpan.FromSeconds(OAuth2Config.DefaultTimeOut); + var url = APIConfig.DefaultBaseUrl + "/oauth2/token"; + var response = httpClient.PostAsync(url, new FormUrlEncodedContent(new List>() + { + new KeyValuePair("grant_type","client_credentials"), + new KeyValuePair("client_id",clientId), + new KeyValuePair("client_secret", clientSecret), + })).Result; + var str = response.Content.ReadAsStringAsync().Result; + var res = JObject.Parse(str); + expireTimeStamp = long.Parse(GetTimeStamp()) + 7200; + token = res["access_token"].ToString(); + Console.WriteLine(token + " expire:" + expireTimeStamp + " now:" + GetTimeStamp()); + } + } + catch (Exception ex) + { + throw ex; + } } + + public static string GetTimeStamp() + { + TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0); + return Convert.ToInt64(ts.TotalSeconds).ToString(); + } + #endregion + + #region 对外暴露的公有方法 /// /// @@ -38,10 +102,10 @@ public static string CallApi(string url, string method) /// public static void SyncToCsv(string path) where T : class { - if (OauthConfig.ClientId != null && OauthConfig.ClientSecret != null && ApiConfig.ApiUrl != null - && ApiConfig.ApiParameters != null && ApiConfig.OutputFilePath != null) + if (OAuth2Config.ClientId != null && OAuth2Config.ClientSecret != null && APIConfig.ApiUrl != null + && APIConfig.ApiParameters != null && APIConfig.OutputFilePath != null) { - var expandos = GetAllRows(ApiConfig.PageSize); + var expandos = GetAllRows(APIConfig.PageSize); if (expandos == null) { Console.WriteLine("bad request,check api configs"); @@ -71,10 +135,10 @@ public static void SyncToCsv(string path) where T : class public static List SyncToModel() where T : class { List list = new List(); - if (OauthConfig.ClientId != null && OauthConfig.ClientSecret != null && ApiConfig.ApiUrl != null - && ApiConfig.ApiParameters != null && ApiConfig.OutputFilePath != null) + if (OAuth2Config.ClientId != null && OAuth2Config.ClientSecret != null && APIConfig.ApiUrl != null + && APIConfig.ApiParameters != null && APIConfig.OutputFilePath != null) { - list = GetAllRows(ApiConfig.PageSize); + list = GetAllRows(APIConfig.PageSize); if (list == null) { Console.WriteLine("bad request,check api configs"); @@ -96,9 +160,9 @@ public static List SyncToModel() where T : class /// public static void SyncToDb(SqlSugarDbContext db) where T : class, new() { - int bulckPageSize = ApiConfig.BatchSize; - if (OauthConfig.ClientId != null && OauthConfig.ClientSecret != null && ApiConfig.ApiUrl != null - && ApiConfig.ApiParameters != null && ApiConfig.OutputFilePath != null) + int bulckPageSize = APIConfig.BatchSize; + if (OAuth2Config.ClientId != null && OAuth2Config.ClientSecret != null && APIConfig.ApiUrl != null + && APIConfig.ApiParameters != null && APIConfig.OutputFilePath != null) { db.Db.CodeFirst.InitTables(typeof(T)); int pageNum; @@ -106,7 +170,7 @@ public static List SyncToModel() where T : class List allRows = new List(); for (pageNum = 1; pageNum < int.MaxValue; pageNum++) { - var row = GetRows(pageNum, ApiConfig.PageSize); + var row = GetRows(pageNum, APIConfig.PageSize); if (row.Count != 0) { allRows.AddRange(row); @@ -142,9 +206,9 @@ public static List SyncToModel() where T : class /// public static void SyncToDbMerge(SqlSugarDbContext db) where T : class, new() { - int bulckPageSize = ApiConfig.BatchSize; - if (OauthConfig.ClientId != null && OauthConfig.ClientSecret != null && ApiConfig.ApiUrl != null - && ApiConfig.ApiParameters != null && ApiConfig.OutputFilePath != null) + int bulckPageSize = APIConfig.BatchSize; + if (OAuth2Config.ClientId != null && OAuth2Config.ClientSecret != null && APIConfig.ApiUrl != null + && APIConfig.ApiParameters != null && APIConfig.OutputFilePath != null) { db.Db.CodeFirst.InitTables(typeof(T)); int pageNum; @@ -152,7 +216,7 @@ public static List SyncToModel() where T : class List allRows = new List(); for (pageNum = 1; pageNum < int.MaxValue; pageNum++) { - var row = GetRows(pageNum, ApiConfig.PageSize); + var row = GetRows(pageNum, APIConfig.PageSize); if (row.Count != 0) { allRows.AddRange(row); @@ -180,38 +244,38 @@ public static List SyncToModel() where T : class } - public static void AddParameter(string key, string value) + public static void SetParameter(string key, string value) { //如果添加了重复的参数,新的值覆盖原有值 - if (ApiConfig.ApiParameters.ContainsKey(key)) + if (APIConfig.ApiParameters.ContainsKey(key)) { - ApiConfig.ApiParameters[key] = value; + APIConfig.ApiParameters[key] = value; } else { - ApiConfig.ApiParameters.Add(key, value); + APIConfig.ApiParameters.Add(key, value); } } public static void DeleteParameter(string key, string value) { - if (ApiConfig.ApiParameters.ContainsKey(key)) + if (APIConfig.ApiParameters.ContainsKey(key)) { - ApiConfig.ApiParameters.Remove(key); + APIConfig.ApiParameters.Remove(key); } } private static string GenerateUrl(int pageNum, int pageSize) { - string url = string.Format("{0}{1}?pageNum={2}&pageSize={3}", ApiConfig.DefaultBaseUrl, ApiConfig.ApiUrl, pageNum, pageSize); - if (ApiConfig.ApiParameters.Count == 0) + string url = string.Format("{0}{1}?pageNum={2}&pageSize={3}", APIConfig.DefaultBaseUrl, APIConfig.ApiUrl, pageNum, pageSize); + if (APIConfig.ApiParameters.Count == 0) { Console.WriteLine("no params"); return url; } - foreach (KeyValuePair keyValuePair in ApiConfig.ApiParameters) + foreach (KeyValuePair keyValuePair in APIConfig.ApiParameters) { if (!url.Contains("?")) url += "?" + keyValuePair.Key + "=" + keyValuePair.Value;