Use generics and reflection to manage the configuration file, convert the Model to a data row, and convert the data row to a Model. The configuration file model
Use Cases: website configuration items. For ease of management, the website has several Model classes to manage configuration files,
For example, ConfigWebsiteModel is used to manage basic information.
ConfigSeoModel is used to manage SEO Information
ConfigCacheModel is used to manage website Cache Information
Duplicate attribute fields cannot exist between models.
Now they need to be stored in the database and read from the database and converted into a Model for modification. the reason that List <T> and Dictionary <T, T> are not used is to use the powerful data self-check capability provided by MVC.
Core class: two methods: Load and Save Load <T t> pass in T and return T's instance Save to pass in T and store it in the database
Using System; using System. collections. generic; using System. linq; using System. web; using System. data; using System. text; using ChengChenXu. blog. models; using System. reflection; using System. data. sqlClient; namespace ChengChenXu. blog. DAL. sqlServer {public class ConfigModelDAL: IConfigModelDAL {private readonly string tableName = "blog_Config"; // table name private readonly string columnKey = "c_Key "; // key column name private readonly string columnValue = "c_Value"; // Value column name private readonly string columnType = "c_Type "; // Type column name // <summary> // load // </summary> // <typeparam name = "T"> </typeparam> // <returns> </returns> public T Load <T> () {// use sqlhelper to obtain the datatable string SQL = "select * from" + tableName; DataTable dt = SqlHelper. executeDataTable (SQL); // if (dt. rows. count = 0) return default (T); // convert table rows into columns, temporary table DataTable temp = new DataTable (); foreach (DataRow dr in dt. rows) {// Add a column and set the Data Type of the column DataColumn dc = new DataColumn (); dc. columnName = dr [columnKey]. toString (); // set the Data Type dc based on the string. dataType = System. type. getType (dr [columnType]. toString (); temp. columns. add (dc); // if the first column is used, Add an int index = temp. columns. count-1; if (temp. rows. count = 0) temp. rows. add (); // if it is not the first example, the row must already exist and the value temp is assigned directly. rows [0] [index] = dr [columnValue];} if (temp. columns. count = 0) return default (T); // convert a temporary table to a Model and return temp. rows [0]. toModel <T> ();} /// <summary> /// save /// </summary> /// <typeparam name = "T"> </typeparam> /// <param name =" t "> </param> public void Save <T> (T t) {// obtain all attributes of the object Using Reflection string attributeName = String. empty; PropertyInfo [] propertys = t. getType (). getProperties (); // obtain the database configuration table and place it in the memory. Compare whether the data already has a DataTable dt = new DataTable (); if (propertys. length> 0) {dt = SqlHelper. executeDataTable ("select * from" + tableName + ""); // you can specify a primary key for a table. dt. primaryKey = new [] {(dt. columns [columnKey]) };}// Save the object attributes to the database foreach (PropertyInfo pi in propertys) {// obtain the attribute value var a = pi. getValue (t, null); // if (a = NULL) {SqlHelper. executeNonQuery ("delete from" + tableName + "where" + columnKey + "= '" + pi. name + "'"); continue;} // prepare the SQL parameter SqlParameter [] parameters = SqlHelper. creatParameters (new string [] {"Key", "Value", "Type"}, new object [] {pi. name, a,. getType (). toString ()}); // check whether the property already exists in the database if (dt. rows. contains (pi. name) {// The property SqlHelper is updated. executeNonQuery ("update" + tableName + "set" + columnValue + "= @ Value," + columnType + "= @ Type where" + columnKey + "= @ Key ", parameters);} else {// The insert attribute SqlHelper does not exist. executeNonQuery ("insert into" + tableName + "(" + columnKey + "," + columnValue + "," + columnType + ") values (@ key, @ value, @ type) ", parameters );}}}}}
The preceding class uses a DataTable extension class to extend the ToModle method of DataRow. The Code is as follows:
/// <Summary> /// class description: extends the DataTable and DataRow methods and converts them to an object set or object code Creator: cheng chenxu // contact: Email: 97391519@qq.com // Blog: http://chengchenxu.com/// Modification date: 2018-02-28 // Note: This extension class can greatly simplify the operation, but the performance is low, big data and high performance requirements are used with caution. /// if this class is put in the App_Code folder of asp.net, there will be a compilation error. If it is put elsewhere, there will be no such problem. // </summary> using System; using System. collections. generic; using System. linq; using System. web; using System. data; using System. reflection; namespace ChengChenXu. blog. DAL {internal static class DataTableExtensions {// <summary> // converts DataRow to a corresponding object, and adds an extension method to DataRow for ease of use. /// </summary> /// <Typeparam name = "T"> </typeparam> // <param name = "dr"> </param> // <returns> </returns> internal static T toModel <T> (this DataRow dr) {T t = Activator. createInstance <T> (); // obtain the public attributes of this Model Using Reflection string attributeName = String. empty; PropertyInfo [] propertys = t. getType (). getProperties (); foreach (PropertyInfo pi in propertys) {attributeName = pi. name; // check whether the DataTable contains this column // The column Name of DataRow must be consistent with the object attribute Name // Note: The Case sensitivity here is not if (dr. Table. Columns. Contains (attributeName) {// determines whether this attribute is read-only (does not contain set construction) if (! Pi. CanWrite) {continue;} // assign var value = dr [attributeName] To the attribute; if (value! = DBNull. value) {pi. setValue (t, value, null) ;}} return t ;} /// <summary> /// convert a able to an object set /// </summary> /// <typeparam name = "T"> </typeparam> // /<param name = "dt"> </param> // <returns> </returns> internal static List <T> ToModelList <T> (this DataTable dt) {List <T> list = new List <T> (); // call the ToModel method to add List for (int I = 0; I <dt. rows. count; I ++) {T t = Activator. createInstance <T> (); t = dt. rows [I]. toModel <T> (); list. add (t) ;}return list ;}}}
SqlHelper is also used for database operations. This is very simple and it is not followed by code.
Usage:
1. These four attributes correspond to the table name and column name in the database, which can be customized, for example.
Private readonly string tableName = "blog_Config"; // table name private readonly string columnKey = "c_Key"; // key column name private readonly string columnValue = "c_Value "; // Value column name private readonly string columnType = "c_Type"; // Type column name
The key must be set as the primary key. All types are varchar. The length depends on the situation.
2 database link strings are defined in sqlHelper class, SqlHelper class reference article: http://www.chengchenxu.com/Article/11/sqlhelper
3. Create a Model for Load and Save operations.
Public class ConfigSeoModel {[Display (Name = "Meta KeyWord")] public string KeyWord {get; set;} [Display (Name = "Meta description")] public string Description {get; set ;}/// ConfigModelDAL = new ConfigModelDAL (); // a new Model ConfigSeoModel model = new ConfigSeoModel (); model. keyWord = "KeyWord"; model. description = "Description" // Save the dal. save <ConfigSeoModel> (model); // read ConfigSeoModel model = dal. load <ConfigModel> ();
This article is original to the blogger. for reprinting, please keep the source:
Http://www.chengchenxu.com/Article/24/fanxing