博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MS CRM 2011 RetrieveMultiple with JScript JQuery Silverlight LINQ FetchXML and QueryExpression
阅读量:6211 次
发布时间:2019-06-21

本文共 61974 字,大约阅读时间需要 206 分钟。

 

 

(一) JScript

JScript一次最多返回50条数据,想要获得更多数据,需要使用__next 对象

 

1. 同步操作返回少于50条数据

                                                

 

if (typeof (TestLibrary) == "undefined") {     TestLibrary = { __namespace: true }; }TestLibrary = {     Name: "TestLibrary",     _context: function () {         if (typeof GetGlobalContext != "undefined")         { return GetGlobalContext(); }         else {             if (typeof Xrm != "undefined") {                 return Xrm.Page.context;             }             else             { throw new Error("Context is not available."); }         }     },     _getServerUrl: function () {         var serverUrl = TestLibrary._context().getServerUrl()         if (serverUrl.match(/\/$/)) {             serverUrl = serverUrl.substring(0, serverUrl.length - 1);         }         return serverUrl;     },     _ODataPath: function () {         return TestLibrary._getServerUrl() + "/XRMServices/2011/OrganizationData.svc/";     } }

 

2. 同步操作返回大于50条数据

                                                

 

3. 异步操作返回少于50条数据

                                              

 

4. 异步操作返回大于50条数据

                                              

 

TestLibrary.js是SDK.REST.js 的精简版,你完全可以也使用SDK.REST.js

if (typeof (TestLibrary) == "undefined") {     TestLibrary = { __namespace: true }; }TestLibrary = {     Name: "TestLibrary",     _context: function () {         if (typeof GetGlobalContext != "undefined")         { return GetGlobalContext(); }         else {             if (typeof Xrm != "undefined") {                 return Xrm.Page.context;             }             else             { throw new Error("Context is not available."); }         }     },     _getServerUrl: function () {         var serverUrl = TestLibrary._context().getServerUrl()         if (serverUrl.match(/\/$/)) {             serverUrl = serverUrl.substring(0, serverUrl.length - 1);         }         return serverUrl;     },     _ODataPath: function () {         return TestLibrary._getServerUrl() + "/XRMServices/2011/OrganizationData.svc/";     },     RetrieveMultipleRecords: function (type, options, successCallback, errorCallback, OnComplete) {                var optionsString;         if (options != null) {             if (options.charAt(0) != "?") {                 optionsString = "?" + options;             }             else             { optionsString = options; }         }        var req = new XMLHttpRequest();         req.open("GET", TestLibrary._ODataPath() + type + "Set" + optionsString, true);                req.setRequestHeader("Accept", "application/json");         req.setRequestHeader("Content-Type", "application/json; charset=utf-8");         req.onreadystatechange = function () {             if (this.readyState == 4 /* complete */) {                 if (this.status == 200) {                     var returned = JSON.parse(this.responseText).d;                     successCallback(returned.results);                     if (returned.__next != null) {                         var queryOptions = returned.__next.substring((TestLibrary._ODataPath() + type + "Set").length);                                                TestLibrary.RetrieveMultipleRecords(type, queryOptions, successCallback, errorCallback, OnComplete);                     }                     else                     { OnComplete(); }                 }                 else {                     errorCallback(TestLibrary._errorHandler(this));                 }             }         };         req.send();     },     _errorHandler: function (req) {                if (req.status == 12029)         { return new Error("The attempt to connect to the server failed."); }         if (req.status == 12007)         { return new Error("The server name could not be resolved."); }         var errorText;         try             { errorText = JSON.parse(req.responseText).error.message.value; }         catch (e)             { errorText = req.responseText }        return new Error("Error : " +             req.status + ": " +             req.statusText + ": " + errorText);     } }

 

SDK.REST.js:

if (typeof (SDK) == "undefined") { SDK = { __namespace: true }; } SDK.REST = { _context: function () {   ///   /// Private function to the context object.   ///   ///
Context
if (typeof GetGlobalContext != "undefined") { return GetGlobalContext(); } else { if (typeof Xrm != "undefined") { return Xrm.Page.context; } else { throw new Error("Context is not available."); } } }, _getServerUrl: function () { /// /// Private function to return the server URL from the context /// ///
String
var serverUrl = this._context().getServerUrl() if (serverUrl.match(/\/$/)) { serverUrl = serverUrl.substring(0, serverUrl.length - 1); } return serverUrl; }, _ODataPath: function () { /// /// Private function to return the path to the REST endpoint. /// ///
String
return this._getServerUrl() + "/XRMServices/2011/OrganizationData.svc/"; }, _errorHandler: function (req) { /// /// Private function return an Error object to the errorCallback /// /// /// The XMLHttpRequest response that returned an error. /// ///
Error
//Error descriptions come from http://support.microsoft.com/kb/193625 if (req.status == 12029) { return new Error("The attempt to connect to the server failed."); } if (req.status == 12007) { return new Error("The server name could not be resolved."); } var errorText; try { errorText = JSON.parse(req.responseText).error.message.value; } catch (e) { errorText = req.responseText } return new Error("Error : " + req.status + ": " + req.statusText + ": " + errorText); }, _dateReviver: function (key, value) { /// /// Private function to convert matching string values to Date objects. /// /// /// The key used to identify the object property /// /// /// The string value representing a date /// var a; if (typeof value === 'string') { a = /Date\(([-+]?\d+)\)/.exec(value); if (a) { return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10)); } } return value; }, _parameterCheck: function (parameter, message) { /// /// Private function used to check whether required parameters are null or undefined /// /// /// The parameter to check; /// /// /// The error message text to include when the error is thrown. /// if ((typeof parameter === "undefined") || parameter === null) { throw new Error(message); } }, _stringParameterCheck: function (parameter, message) { /// /// Private function used to check whether required parameters are null or undefined /// /// /// The string parameter to check; /// /// /// The error message text to include when the error is thrown. /// if (typeof parameter != "string") { throw new Error(message); } }, _callbackParameterCheck: function (callbackParameter, message) { /// /// Private function used to check whether required callback parameters are functions /// /// /// The callback parameter to check; /// /// /// The error message text to include when the error is thrown. /// if (typeof callbackParameter != "function") { throw new Error(message); } }, createRecord: function (object, type, successCallback, errorCallback) { /// /// Sends an asynchronous request to create a new record. /// /// /// A JavaScript object with properties corresponding to the Schema name of /// entity attributes that are valid for create operations. /// /// /// The Schema Name of the Entity type record to create. /// For an Account record, use "Account" /// /// /// The function that will be passed through and be called by a successful response. /// This function can accept the returned record as a parameter. /// /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._parameterCheck(object, "SDK.REST.createRecord requires the object parameter."); this._stringParameterCheck(type, "SDK.REST.createRecord requires the type parameter is a string."); this._callbackParameterCheck(successCallback, "SDK.REST.createRecord requires the successCallback is a function."); this._callbackParameterCheck(errorCallback, "SDK.REST.createRecord requires the errorCallback is a function."); var req = new XMLHttpRequest(); req.open("POST", encodeURI(this._ODataPath() + type + "Set"), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { if (this.status == 201) { successCallback(JSON.parse(this.responseText, SDK.REST._dateReviver).d); } else { errorCallback(SDK.REST._errorHandler(this)); } } }; req.send(JSON.stringify(object)); }, retrieveRecord: function (id, type, select, expand, successCallback, errorCallback) { /// /// Sends an asynchronous request to retrieve a record. /// /// /// A String representing the GUID value for the record to retrieve. /// /// /// The Schema Name of the Entity type record to retrieve. /// For an Account record, use "Account" /// /// /// A String representing the $select OData System Query Option to control which /// attributes will be returned. This is a comma separated list of Attribute names that are valid for retrieve. /// If null all properties for the record will be returned /// /// /// A String representing the $expand OData System Query Option value to control which /// related records are also returned. This is a comma separated list of of up to 6 entity relationship names /// If null no expanded related records will be returned. /// /// /// The function that will be passed through and be called by a successful response. /// This function must accept the returned record as a parameter. /// /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._stringParameterCheck(id, "SDK.REST.retrieveRecord requires the id parameter is a string."); this._stringParameterCheck(type, "SDK.REST.retrieveRecord requires the type parameter is a string."); if (select != null) this._stringParameterCheck(select, "SDK.REST.retrieveRecord requires the select parameter is a string."); if (expand != null) this._stringParameterCheck(expand, "SDK.REST.retrieveRecord requires the expand parameter is a string."); this._callbackParameterCheck(successCallback, "SDK.REST.retrieveRecord requires the successCallback parameter is a function."); this._callbackParameterCheck(errorCallback, "SDK.REST.retrieveRecord requires the errorCallback parameter is a function."); var systemQueryOptions = ""; if (select != null || expand != null) { systemQueryOptions = "?"; if (select != null) { var selectString = "$select=" + select; if (expand != null) { selectString = selectString + "," + expand; } systemQueryOptions = systemQueryOptions + selectString; } if (expand != null) { systemQueryOptions = systemQueryOptions + "&$expand=" + expand; } } var req = new XMLHttpRequest(); req.open("GET", encodeURI(this._ODataPath() + type + "Set(guid'" + id + "')" + systemQueryOptions), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { if (this.status == 200) { successCallback(JSON.parse(this.responseText, SDK.REST._dateReviver).d); } else { errorCallback(SDK.REST._errorHandler(this)); } } }; req.send(); }, updateRecord: function (id, object, type, successCallback, errorCallback) { /// /// Sends an asynchronous request to update a record. /// /// /// A String representing the GUID value for the record to retrieve. /// /// /// A JavaScript object with properties corresponding to the Schema Names for /// entity attributes that are valid for update operations. /// /// /// The Schema Name of the Entity type record to retrieve. /// For an Account record, use "Account" /// /// /// The function that will be passed through and be called by a successful response. /// Nothing will be returned to this function. /// /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._stringParameterCheck(id, "SDK.REST.updateRecord requires the id parameter."); this._parameterCheck(object, "SDK.REST.updateRecord requires the object parameter."); this._stringParameterCheck(type, "SDK.REST.updateRecord requires the type parameter."); this._callbackParameterCheck(successCallback, "SDK.REST.updateRecord requires the successCallback is a function."); this._callbackParameterCheck(errorCallback, "SDK.REST.updateRecord requires the errorCallback is a function."); var req = new XMLHttpRequest(); req.open("POST", encodeURI(this._ODataPath() + type + "Set(guid'" + id + "')"), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("X-HTTP-Method", "MERGE"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { if (this.status == 204 || this.status == 1223) { successCallback(); } else { errorCallback(SDK.REST._errorHandler(this)); } } }; req.send(JSON.stringify(object)); }, deleteRecord: function (id, type, successCallback, errorCallback) { /// /// Sends an asynchronous request to delete a record. /// /// /// A String representing the GUID value for the record to delete. /// /// /// The Schema Name of the Entity type record to delete. /// For an Account record, use "Account" /// /// /// The function that will be passed through and be called by a successful response. /// Nothing will be returned to this function. /// /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._stringParameterCheck(id, "SDK.REST.deleteRecord requires the id parameter."); this._stringParameterCheck(type, "SDK.REST.deleteRecord requires the type parameter."); this._callbackParameterCheck(successCallback, "SDK.REST.deleteRecord requires the successCallback is a function."); this._callbackParameterCheck(errorCallback, "SDK.REST.deleteRecord requires the errorCallback is a function."); var req = new XMLHttpRequest(); req.open("POST", encodeURI(this._ODataPath() + type + "Set(guid'" + id + "')"), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("X-HTTP-Method", "DELETE"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { if (this.status == 204 || this.status == 1223) { successCallback(); } else { errorCallback(SDK.REST._errorHandler(this)); } } }; req.send();}, retrieveMultipleRecords: function (type, options, successCallback, errorCallback, OnComplete) { /// /// Sends an asynchronous request to retrieve records. /// /// /// The Schema Name of the Entity type record to retrieve. /// For an Account record, use "Account" /// /// /// A String representing the OData System Query Options to control the data returned /// /// /// The function that will be passed through and be called for each page of records returned. /// Each page is 50 records. If you expect that more than one page of records will be returned, /// this function should loop through the results and push the records into an array outside of the function. /// Use the OnComplete event handler to know when all the records have been processed. /// /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// /// /// The function that will be called when all the requested records have been returned. /// No parameters are passed to this function. /// this._stringParameterCheck(type, "SDK.REST.retrieveMultipleRecords requires the type parameter is a string."); if (options != null) this._stringParameterCheck(options, "SDK.REST.retrieveMultipleRecords requires the options parameter is a string."); this._callbackParameterCheck(successCallback, "SDK.REST.retrieveMultipleRecords requires the successCallback parameter is a function."); this._callbackParameterCheck(errorCallback, "SDK.REST.retrieveMultipleRecords requires the errorCallback parameter is a function."); this._callbackParameterCheck(OnComplete, "SDK.REST.retrieveMultipleRecords requires the OnComplete parameter is a function."); var optionsString; if (options != null) { if (options.charAt(0) != "?") { optionsString = "?" + options; } else { optionsString = options; } } var req = new XMLHttpRequest(); req.open("GET", this._ODataPath() + type + "Set" + optionsString, true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { if (this.status == 200) { var returned = JSON.parse(this.responseText, SDK.REST._dateReviver).d; successCallback(returned.results); if (returned.__next != null) { var queryOptions = returned.__next.substring((SDK.REST._ODataPath() + type + "Set").length); SDK.REST.retrieveMultipleRecords(type, queryOptions, successCallback, errorCallback, OnComplete); } else { OnComplete(); } } else { errorCallback(SDK.REST._errorHandler(this)); } } }; req.send(); }, associateRecords: function (parentId, parentType, relationshipName, childId, childType, successCallback, errorCallback) { this._stringParameterCheck(parentId, "SDK.REST.associateRecords requires the parentId parameter is a string."); /// /// The Id of the record to be the parent record in the relationship /// /// /// The Schema Name of the Entity type for the parent record. /// For an Account record, use "Account" /// /// /// The Schema Name of the Entity Relationship to use to associate the records. /// To associate account records as a Parent account, use "Referencedaccount_parent_account" /// /// /// The Id of the record to be the child record in the relationship /// /// /// The Schema Name of the Entity type for the child record. /// For an Account record, use "Account" /// /// /// The function that will be passed through and be called by a successful response. /// Nothing will be returned to this function. /// /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._stringParameterCheck(parentType, "SDK.REST.associateRecords requires the parentType parameter is a string."); this._stringParameterCheck(relationshipName, "SDK.REST.associateRecords requires the relationshipName parameter is a string."); this._stringParameterCheck(childId, "SDK.REST.associateRecords requires the childId parameter is a string."); this._stringParameterCheck(childType, "SDK.REST.associateRecords requires the childType parameter is a string."); this._callbackParameterCheck(successCallback, "SDK.REST.associateRecords requires the successCallback parameter is a function."); this._callbackParameterCheck(errorCallback, "SDK.REST.associateRecords requires the errorCallback parameter is a function."); var req = new XMLHttpRequest(); req.open("POST", encodeURI(this._ODataPath() + parentType + "Set(guid'" + parentId + "')/$links/" + relationshipName), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { if (this.status == 204 || this.status == 1223) { successCallback(); } else { errorCallback(SDK.REST._errorHandler(this)); } } }; var childEntityReference = {} childEntityReference.uri = this._ODataPath() + "/" + childType + "Set(guid'" + childId + "')"; req.send(JSON.stringify(childEntityReference)); }, disassociateRecords: function (parentId, parentType, relationshipName, childId, successCallback, errorCallback) { this._stringParameterCheck(parentId, "SDK.REST.disassociateRecords requires the parentId parameter is a string."); /// /// The Id of the record to be the parent record in the relationship /// /// /// The Schema Name of the Entity type for the parent record. /// For an Account record, use "Account" /// /// /// The Schema Name of the Entity Relationship to use to disassociate the records. /// To disassociate account records as a Parent account, use "Referencedaccount_parent_account" /// /// /// The Id of the record to be disassociated as the child record in the relationship /// /// /// The function that will be passed through and be called by a successful response. /// Nothing will be returned to this function. /// /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._stringParameterCheck(parentType, "SDK.REST.disassociateRecords requires the parentType parameter is a string."); this._stringParameterCheck(relationshipName, "SDK.REST.disassociateRecords requires the relationshipName parameter is a string."); this._stringParameterCheck(childId, "SDK.REST.disassociateRecords requires the childId parameter is a string."); this._callbackParameterCheck(successCallback, "SDK.REST.disassociateRecords requires the successCallback parameter is a function."); this._callbackParameterCheck(errorCallback, "SDK.REST.disassociateRecords requires the errorCallback parameter is a function."); var req = new XMLHttpRequest(); req.open("POST", encodeURI(this._ODataPath() + parentType + "Set(guid'" + parentId + "')/$links/" + relationshipName + "(guid'" + childId + "')"), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("X-HTTP-Method", "DELETE"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { if (this.status == 204 || this.status == 1223) { successCallback(); } else { errorCallback(SDK.REST._errorHandler(this)); } } }; req.send(); }, __namespace: true };

 

 

 

(二) JQuery

JQuery使用AJAX,所以全部都是异步操作。在下面的例子中直接使用SDK.JQuery.js

 

                                                   

 

 SDK.JQuery.js

/// 
if (typeof (SDK) == "undefined") { SDK = { __namespace: true }; } SDK.JQuery = { _context: function () { /// /// Private function to the context object. /// ///
Context
if (typeof GetGlobalContext != "undefined") { return GetGlobalContext(); } else { if (typeof Xrm != "undefined") { return Xrm.Page.context; } else { throw new Error("Context is not available."); } } }, _getServerUrl: function () { /// /// Private function to return the server URL from the context /// ///
String
var serverUrl = this._context().getServerUrl() if (serverUrl.match(/\/$/)) { serverUrl = serverUrl.substring(0, serverUrl.length - 1); } return serverUrl; }, _ODataPath: function () { /// /// Private function to return the path to the REST endpoint. /// ///
String
return this._getServerUrl() + "/XRMServices/2011/OrganizationData.svc/"; }, _errorHandler: function (req) { /// /// Private function return an Error object to the errorCallback /// /// /// The XMLHttpRequest response that returned an error. /// ///
Error
return new Error("Error : " + req.status + ": " + req.statusText + ": " + JSON.parse(req.responseText).error.message.value); }, _dateReviver: function (key, value) { /// /// Private function to convert matching string values to Date objects. /// /// /// The key used to identify the object property /// /// /// The string value representing a date /// var a; if (typeof value === 'string') { a = /Date\(([-+]?\d+)\)/.exec(value); if (a) { return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10)); } } return value; }, _parameterCheck: function (parameter, message) { /// /// Private function used to check whether required parameters are null or undefined /// /// /// The parameter to check; /// /// /// The error message text to include when the error is thrown. /// if ((typeof parameter === "undefined") || parameter === null) { throw new Error(message); } }, _stringParameterCheck: function (parameter, message) { /// /// Private function used to check whether required parameters are null or undefined /// /// /// The string parameter to check; /// /// /// The error message text to include when the error is thrown. /// if (typeof parameter != "string") { throw new Error(message); } }, _callbackParameterCheck: function (callbackParameter, message) { /// /// Private function used to check whether required callback parameters are functions /// /// /// The callback parameter to check; /// /// /// The error message text to include when the error is thrown. /// if (typeof callbackParameter != "function") { throw new Error(message); } }, createRecord: function (object, type, successCallback, errorCallback) { /// /// Sends an asynchronous request to create a new record. /// /// /// A JavaScript object with properties corresponding to the Schema name of /// entity attributes that are valid for create operations. /// this._parameterCheck(object, "SDK.JQuery.createRecord requires the object parameter."); /// /// The Schema Name of the Entity type record to create. /// For an Account record, use "Account" /// this._stringParameterCheck(type, "SDK.JQuery.createRecord requires the type parameter is a string."); /// /// The function that will be passed through and be called by a successful response. /// This function can accept the returned record as a parameter. /// this._callbackParameterCheck(successCallback, "SDK.JQuery.createRecord requires the successCallback is a function."); /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._callbackParameterCheck(errorCallback, "SDK.JQuery.createRecord requires the errorCallback is a function."); var jsonEntity = window.JSON.stringify(object); $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", datatype: "json", url: this._ODataPath() + type + "Set", data: jsonEntity, beforeSend: function (xhr) { //Specifying this header ensures that the results will be returned as JSON. xhr.setRequestHeader("Accept", "application/json"); }, success: function (data, textStatus, xhr) { successCallback(data.d); }, error: function (xhr, textStatus, errorThrown) { errorCallback(SDK.JQuery._errorHandler(xhr)); } }); }, retrieveRecord: function (id, type, select, expand, successCallback, errorCallback) { /// /// Sends an asynchronous request to retrieve a record. /// /// /// A String representing the GUID value for the record to retrieve. /// this._stringParameterCheck(id, "SDK.JQuery.retrieveRecord requires the id parameter is a string."); /// /// The Schema Name of the Entity type record to retrieve. /// For an Account record, use "Account" /// this._stringParameterCheck(type, "SDK.JQuery.retrieveRecord requires the type parameter is a string."); /// /// A String representing the $select OData System Query Option to control which /// attributes will be returned. This is a comma separated list of Attribute names that are valid for retrieve. /// If null all properties for the record will be returned /// if (select != null) this._stringParameterCheck(select, "SDK.JQuery.retrieveRecord requires the select parameter is a string."); /// /// A String representing the $expand OData System Query Option value to control which /// related records are also returned. This is a comma separated list of of up to 6 entity relationship names /// If null no expanded related records will be returned. /// if (expand != null) this._stringParameterCheck(expand, "SDK.JQuery.retrieveRecord requires the expand parameter is a string."); /// /// The function that will be passed through and be called by a successful response. /// This function must accept the returned record as a parameter. /// this._callbackParameterCheck(successCallback, "SDK.JQuery.retrieveRecord requires the successCallback parameter is a function."); /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._callbackParameterCheck(errorCallback, "SDK.JQuery.retrieveRecord requires the errorCallback parameter is a function."); var systemQueryOptions = ""; if (select != null || expand != null) { systemQueryOptions = "?"; if (select != null) { var selectString = "$select=" + select; if (expand != null) { selectString = selectString + "," + expand; } systemQueryOptions = systemQueryOptions + selectString; } if (expand != null) { systemQueryOptions = systemQueryOptions + "&$expand=" + expand; } } $.ajax({ type: "GET", contentType: "application/json; charset=utf-8", datatype: "json", url: this._ODataPath() + type + "Set" + "(guid'" + id + "')" + systemQueryOptions, beforeSend: function (xhr) { //Specifying this header ensures that the results will be returned as JSON. xhr.setRequestHeader("Accept", "application/json"); }, success: function (data, textStatus, xhr) { //JQuery does not provide an opportunity to specify a date reviver so this code // parses the xhr.responseText rather than use the data parameter passed by JQuery. successCallback(JSON.parse(xhr.responseText, SDK.JQuery._dateReviver).d); }, error: function (xhr, textStatus, errorThrown) { errorCallback(SDK.JQuery._errorHandler(xhr)); } }); }, updateRecord: function (id, object, type, successCallback, errorCallback) { /// /// Sends an asynchronous request to update a record. /// /// /// A String representing the GUID value for the record to retrieve. /// this._stringParameterCheck(id, "SDK.JQuery.updateRecord requires the id parameter."); /// /// A JavaScript object with properties corresponding to the Schema Names for /// entity attributes that are valid for update operations. /// this._parameterCheck(object, "SDK.JQuery.updateRecord requires the object parameter."); /// /// The Schema Name of the Entity type record to retrieve. /// For an Account record, use "Account" /// this._stringParameterCheck(type, "SDK.JQuery.updateRecord requires the type parameter."); /// /// The function that will be passed through and be called by a successful response. /// Nothing will be returned to this function. /// this._callbackParameterCheck(successCallback, "SDK.JQuery.updateRecord requires the successCallback is a function."); /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._callbackParameterCheck(errorCallback, "SDK.JQuery.updateRecord requires the errorCallback is a function."); var jsonEntity = window.JSON.stringify(object); $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", datatype: "json", data: jsonEntity, url: this._ODataPath() + type + "Set" + "(guid'" + id + "')", beforeSend: function (xhr) { //Specifying this header ensures that the results will be returned as JSON. xhr.setRequestHeader("Accept", "application/json"); //Specify the HTTP method MERGE to update just the changes you are submitting. xhr.setRequestHeader("X-HTTP-Method", "MERGE"); }, success: function (data, textStatus, xhr) { //Nothing is returned to the success function successCallback(); }, error: function (xhr, textStatus, errorThrown) { errorCallback(SDK.JQuery._errorHandler(xhr)); } }); }, deleteRecord: function (id, type, successCallback, errorCallback) { /// /// Sends an asynchronous request to delete a record. /// /// /// A String representing the GUID value for the record to delete. /// this._stringParameterCheck(id, "SDK.JQuery.deleteRecord requires the id parameter."); /// /// The Schema Name of the Entity type record to delete. /// For an Account record, use "Account" /// this._stringParameterCheck(type, "SDK.JQuery.deleteRecord requires the type parameter."); /// /// The function that will be passed through and be called by a successful response. /// Nothing will be returned to this function. /// this._callbackParameterCheck(successCallback, "SDK.JQuery.deleteRecord requires the successCallback is a function."); /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._callbackParameterCheck(errorCallback, "SDK.JQuery.deleteRecord requires the errorCallback is a function."); $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", datatype: "json", url: this._ODataPath() + type + "Set(guid'" + id + "')", beforeSend: function (XMLHttpRequest) { //Specifying this header ensures that the results will be returned as JSON. XMLHttpRequest.setRequestHeader("Accept", "application/json"); //Specify the HTTP method DELETE to perform a delete operation. XMLHttpRequest.setRequestHeader("X-HTTP-Method", "DELETE"); }, success: function (data, textStatus, xhr) { // Nothing is returned to the success function. successCallback(); }, error: function (xhr, textStatus, errorThrown) { errorCallback(SDK.JQuery._errorHandler(xhr)); } }); }, retrieveMultipleRecords: function (type, options, successCallback, errorCallback, OnComplete) { /// /// Sends an asynchronous request to retrieve records. /// /// /// The Schema Name of the Entity type records to retrieve /// For an Account record, use "Account" /// this._stringParameterCheck(type, "SDK.JQuery.retrieveMultipleRecords requires the type parameter is a string."); /// /// A String representing the OData System Query Options to control the data returned /// Do not include the $top option, use the top parameters to set the maximum number of records to return. /// if (options != null) this._stringParameterCheck(options, "SDK.JQuery.retrieveMultipleRecords requires the options parameter is a string."); /// /// The function that will be passed through and be called for each page of records returned. /// This function should loop through the results and push the records into an array. /// this._callbackParameterCheck(successCallback, "SDK.JQuery.retrieveMultipleRecords requires the successCallback parameter is a function."); /// /// The function that will be passed through and be called by a failed response. /// This function must accept an Error object as a parameter. /// this._callbackParameterCheck(errorCallback, "SDK.JQuery.retrieveMultipleRecords requires the errorCallback parameter is a function."); /// /// The function that will be called when all the requested records have been returned. /// No parameters are passed to this function. /// this._callbackParameterCheck(OnComplete, "SDK.JQuery.retrieveMultipleRecords requires the OnComplete parameter is a function."); var optionsString; if (options != null) { if (options.charAt(0) != "?") { optionsString = "?" + options; } else { optionsString = options; } } $.ajax({ type: "GET", contentType: "application/json; charset=utf-8", datatype: "json", url: this._ODataPath() + type + "Set" + optionsString, beforeSend: function (XMLHttpRequest) { //Specifying this header ensures that the results will be returned as JSON. XMLHttpRequest.setRequestHeader("Accept", "application/json"); }, success: function (data, textStatus, xhr) { if (data && data.d && data.d.results) { successCallback(JSON.parse(xhr.responseText, SDK.JQuery._dateReviver).d.results); if (data.d.__next != null) { var queryOptions = data.d.__next.substring((SDK.JQuery._ODataPath() + type + "Set").length); SDK.JQuery.retrieveMultipleRecords(type, queryOptions, successCallback, errorCallback, OnComplete); } else { OnComplete(); } } }, error: function (xhr, textStatus, errorThrown) { errorCallback(SDK.JQuery._errorHandler(xhr)); } }); }, __namespace: true };

 

 

(三) Silverlight

Silverlight使用的都是异步操作。参见。

 

1. 返回少于50条记录

 

using System; using System.Data.Services.Client; using System.Linq; using System.Threading; using System.Windows.Controls; using SilverlightApplication2.CrmODataService; using SilverlightApplication2.Utilities;namespace SilverlightApplication2 {     public partial class MainPage : UserControl     {         private SynchronizationContext _syncContext;         private escrmContext _context;         private String _serverUrl;        public MainPage()         {             InitializeComponent();            //Keeps a reference to the UI thread             _syncContext = SynchronizationContext.Current;            //Get the ServerUrl (ServerUrl is formatted differently OnPremise than OnLine)             _serverUrl = ServerUtility.GetServerUrl();            if (!String.IsNullOrEmpty(_serverUrl))             {                //Setup Context                 _context = new escrmContext(new Uri(String.Format("{0}/xrmservices/2011/organizationdata.svc/",                         _serverUrl), UriKind.Absolute));                //This is important because if the entity has new                 //attributes added the code will fail.                 _context.IgnoreMissingProperties = true;                SearchContacts();             }             else             {                 //No ServerUrl was found. Display message.                 MessagePanel.Children.Add(new TextBlock()                 {                     Text =                         "Unable to access server url. Launch this Silverlight " +                         "Web Resource from a CRM Form OR host it in a valid " +                         "HTML Web Resource with a " +                         ""                 });             }         }        private void SearchContacts()         {             DataServiceQuery
query = (DataServiceQuery
)_context.ContactSet.Where(x => x.StateCode.Value.Value == 0); query.BeginExecute(OnContactSearchComplete, query); } private void OnContactSearchComplete(IAsyncResult result) { try { //Get the original query back from the result. DataServiceQuery
query = result.AsyncState as DataServiceQuery
; var itemsource = new DataServiceCollection
(query.EndExecute(result)); this.myDataGrid.ItemsSource = itemsource; myLabel.Content = "There are " + itemsource.Count + " contacts"; } catch (SystemException se) { _syncContext.Send(new SendOrPostCallback(showErrorDetails), se); } } private void showErrorDetails(object ex) { //Assure the control is visible MessagePanel.Visibility = System.Windows.Visibility.Visible; Exception exception = (Exception)ex; String type = exception.GetType().ToString(); MessagePanel.Children.Add(new TextBlock() { Text = String.Format("{0} Message: {1}", type, exception.Message) }); MessagePanel.Children.Add(new TextBlock() { Text = String.Format("Stack: {0}", exception.StackTrace) }); if (exception.InnerException != null) { String exceptType = exception.InnerException.GetType().ToString(); MessagePanel.Children.Add(new TextBlock() { Text = String.Format("InnerException: {0} : {1}", exceptType, exception.InnerException.Message) }); } } } }

 

2. 返回大于50条记录

 

using System; using System.Data.Services.Client; using System.Linq; using System.Threading; using System.Windows.Controls; using SilverlightApplication2.CrmODataService; using SilverlightApplication2.Utilities;namespace SilverlightApplication2 {     public partial class MainPage : UserControl     {         private SynchronizationContext _syncContext;         private escrmContext _context;         private String _serverUrl;         public DataServiceCollection
ContactCollection; public MainPage() { InitializeComponent(); //Keeps a reference to the UI thread _syncContext = SynchronizationContext.Current; //Get the ServerUrl (ServerUrl is formatted differently OnPremise than OnLine) _serverUrl = ServerUtility.GetServerUrl(); if (!String.IsNullOrEmpty(_serverUrl)) { //Setup Context _context = new escrmContext(new Uri(String.Format("{0}/xrmservices/2011/organizationdata.svc/", _serverUrl), UriKind.Absolute)); //This is important because if the entity has new //attributes added the code will fail. _context.IgnoreMissingProperties = true; SearchContacts(); } else { //No ServerUrl was found. Display message. MessagePanel.Children.Add(new TextBlock() { Text = "Unable to access server url. Launch this Silverlight " + "Web Resource from a CRM Form OR host it in a valid " + "HTML Web Resource with a " + "
" }); } } private void SearchContacts() { DataServiceQuery
query = (DataServiceQuery
)_context.ContactSet.AddQueryOption("$select", "FirstName,LastName").Where(x => x.StateCode.Value.Value == 0); query.BeginExecute(ProcessPages
, new PagingContext
() { ServiceContext = _context, Query = query, PageProcessor = delegate(DataServiceCollection
results) { try { if (null == ContactCollection) { ContactCollection = new DataServiceCollection
(_context); ContactCollection.Load(results); } else { for (int i = 0; i < results.Count; i++) { ContactCollection.Add(results[i]); } } myLabel.Content = "There are " + ContactCollection.Count + " contacts"; this.myDataGrid.ItemsSource = ContactCollection; } catch (Exception ex) { _syncContext.Send(new SendOrPostCallback(showErrorDetails), ex); } return true; } }); } private void ProcessPages
(IAsyncResult result) { try { PagingContext
context = (PagingContext
)result.AsyncState; QueryOperationResponse
response; if (null == context.Query) { response = (QueryOperationResponse
)context.ServiceContext.EndExecute
(result); } else { response = (QueryOperationResponse
)context.Query.EndExecute(result); context.Query = null; } DataServiceCollection
results = new DataServiceCollection
(response); if (null != context.PageProcessor && !context.PageProcessor(results)) { //Stop processing return; } DataServiceQueryContinuation
token = results.Continuation; if (null == token) { System.Windows.MessageBox.Show("complete"); return; } context.ServiceContext.BeginExecute(token, ProcessPages
, context); } catch (Exception ex) { throw ex; } } private void showErrorDetails(object ex) { //Assure the control is visible MessagePanel.Visibility = System.Windows.Visibility.Visible; Exception exception = (Exception)ex; String type = exception.GetType().ToString(); MessagePanel.Children.Add(new TextBlock() { Text = String.Format("{0} Message: {1}", type, exception.Message) }); MessagePanel.Children.Add(new TextBlock() { Text = String.Format("Stack: {0}", exception.StackTrace) }); if (exception.InnerException != null) { String exceptType = exception.InnerException.GetType().ToString(); MessagePanel.Children.Add(new TextBlock() { Text = String.Format("InnerException: {0} : {1}", exceptType, exception.InnerException.Message) }); } } } sealed class PagingContext
{ public DataServiceContext ServiceContext { get; set; } public DataServiceQuery
Query { get; set; } public Func
, bool> PageProcessor { get; set; } } }

 

 

(四) LINQ

using System; using Microsoft.Xrm.Sdk.Discovery; using Microsoft.Xrm.Sdk.Client; using System.Configuration; using Microsoft.Xrm.Sdk; using Microsoft.Crm.Sdk.Messages; using System.Linq;namespace CRM.LINQTest {     class Program     {         static void Main(string[] args)         {             string _discoveryServiceAddress = ConfigurationManager.AppSettings["DiscoveryServiceAddress"];             IServiceManagement
serviceManagement = ServiceConfigurationFactory.CreateManagement
(new Uri(_discoveryServiceAddress)); AuthenticationProviderType endpointType = serviceManagement.AuthenticationType; AuthenticationCredentials authCredentials = GetCredentials(endpointType); String organizationUri = ConfigurationManager.AppSettings["OrganizationServiceAddress"]; if (!String.IsNullOrWhiteSpace(organizationUri)) { IServiceManagement
orgServiceManagement = ServiceConfigurationFactory.CreateManagement
(new Uri(organizationUri)); // Set the credentials. AuthenticationCredentials credentials = GetCredentials(endpointType); // Get the organization service proxy. using (OrganizationServiceProxy organizationProxy = GetProxy
(orgServiceManagement, credentials)) { // This statement is required to enable early-bound type support. organizationProxy.EnableProxyTypes(); IOrganizationService _service = (IOrganizationService)organizationProxy; ServiceContext svcContext = new ServiceContext(_service); var accounts = (from a in svcContext.AccountSet select new Account() { Name = a.Name, }).ToArray(); int i = 1; foreach (var a in accounts) { Console.WriteLine(string.Format("{0}/{2}: {1}", i, a.Name, accounts.Count())); i++; } } } } private static AuthenticationCredentials GetCredentials(AuthenticationProviderType endpointType) { string _userName = ConfigurationManager.AppSettings["UserName"]; string _password = ConfigurationManager.AppSettings["Password"]; string _domain = ConfigurationManager.AppSettings["Domain"]; AuthenticationCredentials authCredentials = new AuthenticationCredentials(); switch (endpointType) { case AuthenticationProviderType.ActiveDirectory: authCredentials.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(_userName, _password, _domain); break; case AuthenticationProviderType.Federation: case AuthenticationProviderType.OnlineFederation: authCredentials.ClientCredentials.UserName.UserName = _userName; authCredentials.ClientCredentials.UserName.Password = _password; break; default: break; } return authCredentials; } private static TProxy GetProxy
(IServiceManagement
serviceManagement, AuthenticationCredentials authCredentials) where TService : class where TProxy : ServiceProxy
{ Type classType = typeof(TProxy); if (serviceManagement.AuthenticationType != AuthenticationProviderType.ActiveDirectory) { AuthenticationCredentials tokenCredentials = serviceManagement.Authenticate(authCredentials); // Obtain discovery/organization service proxy for Federated, LiveId and OnlineFederated environments. // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and SecurityTokenResponse. return (TProxy)classType .GetConstructor(new Type[] { typeof(IServiceManagement
), typeof(SecurityTokenResponse) }) .Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse }); } // Obtain discovery/organization service proxy for ActiveDirectory environment. // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and ClientCredentials. return (TProxy)classType .GetConstructor(new Type[] { typeof(IServiceManagement
), typeof(System.ServiceModel.Description.ClientCredentials) }) .Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials }); } } }

 

 

(五) FetchXML

using System; using Microsoft.Xrm.Sdk.Discovery; using Microsoft.Xrm.Sdk.Client; using System.Configuration; using Microsoft.Xrm.Sdk; using Microsoft.Crm.Sdk.Messages; using System.Linq; using System.IO; using System.Xml; using System.Text;namespace CRM.FetchXMLTest {     class Program     {         private static string CreateXml(string xml, int page)         {             StringReader stringReader = new StringReader(xml);             XmlTextReader reader = new XmlTextReader(stringReader);            // Load document             XmlDocument doc = new XmlDocument();             doc.Load(reader);            return CreateXml(doc, page);         }        private static string CreateXml(XmlDocument doc, int page)         {             XmlAttributeCollection attrs = doc.DocumentElement.Attributes;            XmlAttribute pageAttr = doc.CreateAttribute("page");             pageAttr.Value = System.Convert.ToString(page);             attrs.Append(pageAttr);            StringBuilder sb = new StringBuilder(1024);             StringWriter stringWriter = new StringWriter(sb);            XmlTextWriter writer = new XmlTextWriter(stringWriter);             doc.WriteTo(writer);             writer.Close();            return sb.ToString();         }                static void Main(string[] args)         {             string _discoveryServiceAddress = ConfigurationManager.AppSettings["DiscoveryServiceAddress"];             IServiceManagement
serviceManagement = ServiceConfigurationFactory.CreateManagement
(new Uri(_discoveryServiceAddress)); AuthenticationProviderType endpointType = serviceManagement.AuthenticationType; AuthenticationCredentials authCredentials = GetCredentials(endpointType); String organizationUri = ConfigurationManager.AppSettings["OrganizationServiceAddress"]; if (!String.IsNullOrWhiteSpace(organizationUri)) { IServiceManagement
orgServiceManagement = ServiceConfigurationFactory.CreateManagement
(new Uri(organizationUri)); // Set the credentials. AuthenticationCredentials credentials = GetCredentials(endpointType); // Get the organization service proxy. using (OrganizationServiceProxy organizationProxy = GetProxy
(orgServiceManagement, credentials)) { //organizationProxy.Timeout = new TimeSpan(1, 0, 0, 0); string fetch2 = @"
"; int i = 1; // Initialize the page number. int pageNumber = 1; while (true) { // Build fetchXml string with the placeholders. string xml = CreateXml(fetch2, pageNumber); EntityCollection returnCollection = organizationProxy.RetrieveMultiple(new Microsoft.Xrm.Sdk.Query.FetchExpression(xml)); foreach (var a in returnCollection.Entities) { Console.WriteLine(string.Format("{0}: {1}", i, a["name"])); i++; } // Check for morerecords, if it returns 1. if (returnCollection.MoreRecords) { // Increment the page number to retrieve the next page. pageNumber++; } else { // If no more records in the result nodes, exit the loop. break; } } } } } private static AuthenticationCredentials GetCredentials(AuthenticationProviderType endpointType) { string _userName = ConfigurationManager.AppSettings["UserName"]; string _password = ConfigurationManager.AppSettings["Password"]; string _domain = ConfigurationManager.AppSettings["Domain"]; AuthenticationCredentials authCredentials = new AuthenticationCredentials(); switch (endpointType) { case AuthenticationProviderType.ActiveDirectory: authCredentials.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(_userName, _password, _domain); break; case AuthenticationProviderType.Federation: case AuthenticationProviderType.OnlineFederation: authCredentials.ClientCredentials.UserName.UserName = _userName; authCredentials.ClientCredentials.UserName.Password = _password; break; default: break; } return authCredentials; } private static TProxy GetProxy
(IServiceManagement
serviceManagement, AuthenticationCredentials authCredentials) where TService : class where TProxy : ServiceProxy
{ Type classType = typeof(TProxy); if (serviceManagement.AuthenticationType != AuthenticationProviderType.ActiveDirectory) { AuthenticationCredentials tokenCredentials = serviceManagement.Authenticate(authCredentials); // Obtain discovery/organization service proxy for Federated, LiveId and OnlineFederated environments. // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and SecurityTokenResponse. return (TProxy)classType .GetConstructor(new Type[] { typeof(IServiceManagement
), typeof(SecurityTokenResponse) }) .Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse }); } // Obtain discovery/organization service proxy for ActiveDirectory environment. // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and ClientCredentials. return (TProxy)classType .GetConstructor(new Type[] { typeof(IServiceManagement
), typeof(System.ServiceModel.Description.ClientCredentials) }) .Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials }); } } }

 

Retrieve所有记录

private static List
GetAllAccounts(OrganizationServiceProxy organizationProxy) { string fetch2 = @"
"; List
result = new List
(); // Initialize the page number. int pageNumber = 1; while (true) { // Build fetchXml string with the placeholders. string xml = CreateXml(fetch2, pageNumber); EntityCollection returnCollection = organizationProxy.RetrieveMultiple(new Microsoft.Xrm.Sdk.Query.FetchExpression(xml)); foreach (var a in returnCollection.Entities) { result.Add(a); } // Check for morerecords, if it returns 1. if (returnCollection.MoreRecords) { // Increment the page number to retrieve the next page. pageNumber++; } else { // If no more records in the result nodes, exit the loop. break; } } return result; }

 

 

 

(六) Query Expression

// Get the organization service proxy. using (OrganizationServiceProxy organizationProxy = GetProxy
(orgServiceManagement, credentials)) { Microsoft.Xrm.Sdk.Query.QueryExpression query = new Microsoft.Xrm.Sdk.Query.QueryExpression { EntityName = "account", ColumnSet = new ColumnSet("name") }; int i = 1; query.PageInfo = new PagingInfo(); query.PageInfo.PageNumber = 1; query.PageInfo.PagingCookie = null; while (true) { // Retrieve the page. EntityCollection ec = organizationProxy.RetrieveMultiple(query); if (ec.Entities != null) { // Retrieve all records from the result set. foreach (var a in ec.Entities) { Console.WriteLine(string.Format("{0}: {1}", i, a["name"])); i++; } } // Check for more records, if it returns true. if (ec.MoreRecords) { // Increment the page number to retrieve the next page. query.PageInfo.PageNumber++; // Set the paging cookie to the paging cookie returned from current results. query.PageInfo.PagingCookie = ec.PagingCookie; } else { // If no more records are in the result nodes, exit the loop. break; } }}

 

Retrieve所有记录

private static List
GetAllAccounts(OrganizationServiceProxy organizationProxy) { List
result = new List
(); Microsoft.Xrm.Sdk.Query.QueryExpression query = new Microsoft.Xrm.Sdk.Query.QueryExpression { EntityName = "account", ColumnSet = new ColumnSet("name") }; int i = 1; query.PageInfo = new PagingInfo(); query.PageInfo.PageNumber = 1; query.PageInfo.PagingCookie = null; while (true) { // Retrieve the page. EntityCollection ec = organizationProxy.RetrieveMultiple(query); if (ec.Entities != null) { // Retrieve all records from the result set. foreach (var a in ec.Entities) { result.Add(a); } } // Check for more records, if it returns true. if (ec.MoreRecords) { // Increment the page number to retrieve the next page. query.PageInfo.PageNumber++; // Set the paging cookie to the paging cookie returned from current results. query.PageInfo.PagingCookie = ec.PagingCookie; } else { // If no more records are in the result nodes, exit the loop. break; } } return result; }

 

本文转自JF Zhu博客园博客,原文链接: http://www.cnblogs.com/jfzhu/archive/2013/03/07/2947306.html   ,如需转载请自行联系原作者

你可能感兴趣的文章
4-array/heapq/queue模块
查看>>
同样是90后别人家的孩子已经是年薪百万算法工程师,而你呢?
查看>>
关于微信支付
查看>>
设计模式-结构型模式-装饰模式
查看>>
only_full_group_by问题而引发的对group by的深入思考
查看>>
egret之HelloWorld
查看>>
【C】 27_数组的本质分析
查看>>
我是如何将博客转成PDF的
查看>>
【速记】如何在老IE浏览器上将字符串解析成DOM对象
查看>>
【Dubbo源码阅读系列】之 Dubbo SPI 机制
查看>>
Web随机播放音乐,服务器同步歌曲信息,的一种实现方式。
查看>>
Java NIO与IO 区别
查看>>
Homestead 安装 PHP Redis 扩展
查看>>
多层科目任意组合汇总报表的性能优化 (上)
查看>>
Logstash 参考指南(作为Debian或RPM上的服务运行Logstash)
查看>>
leetCode 4 Median of Two Sorted Arrays
查看>>
xshell免费版下载安装
查看>>
基于moment写一个滑动日历
查看>>
移动端:对高度自适应的输入框说不~
查看>>
android开源新闻小程序、3D翻转公告效果、小说检索、Kotlin开发TODO清单等源码...
查看>>