varCounters =Newlist<tuple<int, performancecounter>>(); using(varconn =NewSqlConnection (configurationmanager.connectionstrings["Sqldiagnosticsdb"]. ConnectionString)) {Conn. Open (); stringsql =string. Format ("Select Id,servicename,categoryname,countername,instancename from service_counters where Machinename= ' {0} '", MachineName); foreach(varCounterinchConn. Query<servicecounter>(SQL)) {Logger.infoformat (@"Creating Performance counter: {0}\{1}\{2}\{3}", counter. MachineName??".", counter. CategoryName, counter. CounterName, counter. INSTANCENAME); varPerfCounter =NewPerformanceCounter (counter. CategoryName, counter. CounterName, counter. InstanceName, counter. MachineName??"."); Counters. ADD (Newtuple<int, performancecounter>(counter. Id, PerfCounter)); //First value doesn ' t matter so we should call the counter at least once Try{perfcounter.nextvalue ();} Catch { } } }Here is the definition of Servicecounter
Public classServicecounter { Public intId {Get;Set; } PublicString ServiceName {Get;Set; } PublicString MachineName {Get;Set; } PublicString CategoryName {Get;Set; } PublicString CounterName {Get;Set; } PublicString InstanceName {Get;Set; } PublicString DisplayName {Get;Set; } PublicString DisplayType {Get;Set; } Public OverrideString ToString () {returnString.Format (@"{0}\{1}\{2}\{3}", MachineName??".", CategoryName, CounterName, InstanceName); } }Dapper can also load populate nested objects, considering a situation in which a Category object is returned, taking into account the category properties of the news.
1, when populating the nested object, had to execute the Tolist<> method, otherwise the return ExecuteReader required open and available connections. The current state of the connection is closed, and a single object does not give an error, it is estimated that the connection was closed after the using end, while the nested object was ExecuteReader at the time of the map and had to return the list collection before the using ended.
2, the parameters of nested objects are more, mainly the first two parameters, other parameters can not be set to null. It is especially important to note that the Spliton parameter cannot be empty, otherwise the object is quoted as an error. The Spliton parameter means reading the split column of the second object, starting from which column to read the second object, and if the self-growing column in the table is an ID, you can set this parameter to "id".
Execute method :
Just as the query method retrieves data, the Execute method does not retrieve the data, which is very similar to the Query method, but it always returns the total number (the number of rows affected) instead of an object collection such as Insert update and delete.
Private voidSaveservicesnapshots (ienumerable<servicecountersnapshot>snapshots) { using(varconn =NewSqlConnection (configurationmanager.connectionstrings["Sqldiagnosticsdb"]. ConnectionString)) {Conn. Open (); foreach(varSnapshotinchsnapshots) { //Insert new Snapshot to the databaseConn. Execute (@"INSERT INTO Service_counter_snapshots (SERVICECOUNTERID,SNAPSHOTMACHINENAME,CREATIONTIMEUTC, Servicecountervalue) VALUES (@ServiceCounterId, @SnapshotMachineName, @CreationTimeUtc, @ServiceCounterValue)", snapshot); } } }Servicecountersnapshot is defined as follows:
Public classServicecountersnapshot { Public intId {Get;Set; } Public intServicecounterid {Get;Set; } /// <summary> ///Machine on which the snapshot is taken. /// </summary> PublicString Snapshotmachinename {Get;Set; } PublicDateTime CREATIONTIMEUTC {Get;Set; } Public float? Servicecountervalue {Get;Set; } }