Red de conocimiento informático - Aprendizaje de código fuente - Expresiones de enlace de datos (Parte 2): Un viaje de exploración en .NET (Parte 2)

Expresiones de enlace de datos (Parte 2): Un viaje de exploración en .NET (Parte 2)

Esta sección continúa la introducción a las expresiones de enlace de datos en .NET

Esta sección incluye los siguientes temas

I. El origen y la estructura subyacente del enlace de datos Implementación del método

II.lt; #((DataRowView)Container DataItem)[nombre del campo] gt;lt;#((Type)Container DataItem) miembro gt;lt;#((Type)GetDataItem() ) member gt; ¿Ha utilizado los siete tipos de enlace anteriores y sus variantes? ¿Los has usado? ¿Cómo calificarías su desempeño?

Como repaso, en la Sección 1 hablamos sobre las diversas formas de expresiones de enlace de datos, dónde aparecen en las páginas ASP.NET y cómo a menudo enlazamos Varias formas de datos. vincular expresiones a fuentes de datos relacionadas con bases de datos, como DataView DataTable DataSet

¿Alguna vez has pensado en el método Eval y el método DataBinder Eval? ¿Método de evaluación de DataBinder?

A menudo utilizamos el método Eval en .NET para vincular datos en controles recurrentes (como Repetidor DataList GridView, etc.). Método Eval y DataBinder ¿Cómo se implementan los métodos Eval internamente? ¿Cómo se relacionan?

Implementación de código fuente

Nuestro método Eval de uso común es en realidad un método estático unidireccional de solo lectura de la clase Page y es un método protegido. De hecho, el método Eval de la clase Page hereda de la clase TemplateControl. La clase TemplateControl es una clase abstracta que proporciona propiedades y métodos comunes para la clase Page y la clase UserControl.

Sistema Objeto Sistema Web UI Control Sistema Web UI TemplateControl Sistema Web UI Página Sistema Web UI UserControl El método Eval es un método de la clase TemplateControl. Tienen dos formas

? TemplateControl Eval (String) ¿Evalúa la expresión de enlace de datos?TemplateControl Eval (String String) ¿Evalúa la expresión de enlace de datos utilizando la cadena de formato especificada utilizada para mostrar los resultados

De hecho, la clase TemplateControl también proporciona XPath método y método XPathSelect, utilizados por la clase de página y la herencia de UserControl. Si observa más de cerca la clase Control, que es la clase base de la clase TemplateControl, encontrará que la clase Control en realidad no proporciona métodos como Eval XPath, XPathSelect, etc., por lo que métodos como Eval XPath eventualmente se implementará en la clase TemplateControl.

Ahora ha comprendido que los métodos de enlace de datos como Eval XPath son nuevos métodos de .NET

Los métodos como Eval XPath son nuevos métodos de .NET En la era .NET, a menudo utilizamos el método DateBinder Eval, como

lt; #DataBind Eval (nombre del campo del elemento de datos del contenedor) gt

lt; ) gt;

Se introduce Eval para simplificar la escritura del método DataBinder Eval y reemplazarlo

En ASP NET y superiores, cuando llamamos a Eval, el método Eval utiliza el método GetDataItem. para llamar al método DataBinder Eval para evaluar la expresión. Para entender esto, incluso un vistazo rápido a MSDN es confuso. A menos que conozcamos el código fuente del método Eval, no podemos encontrar ninguna pista. objeto interno protegido Eval(expresión de cadena)

{

this CheckPageExists()

devuelve DataBinder Eval(esta expresión de página GetDataItem())

}

Finalmente, el método GetDataItem() es un método de la clase de página y un nuevo método en .NET. El método GetDataItem() se utiliza para obtener el contenedor DataItem, que es un nuevo. método en el método .NET en lugar del contenedor DataItem. Container DataItem Si alguna vez ha vinculado una matriz o ArrayList a un repetidor, DataList, etc., verá que <#GetDataItem()> y <#Container DataItem> son iguales y puede estar seguro de que el método Eval es de hecho, llamando al método Eval de nivel inferior.

Para descubrir cómo funciona Eval, también necesitamos usar la reflexión para obtener la implementación subyacente del método GetDataItem().

También necesitamos usar la reflexión para obtener el método GetDataItem()

Objeto público GetDataItem()

{

if ((this _dataBindingContext == null) | | ( this _dataBindingContext Count == ))

{

Genera una nueva excepción de operación no válida (SR GetString(Page_MissingDataBindingContext ))

}

Devuelve este _dataBindingContext Peek()

}

Vimos que este _dataBindingContext Peek() se devolvió en el método GatDataItem() y rápidamente pensamos si _dataBindingContext es una pila. De hecho, ¡es una pila! Al observar el código fuente a través de la reflexión, encontraremos que _dataBindingContext es un objeto de pila, por lo que tiene un método Peek que devuelve este _dataBindingContext Peek (), que devuelve el elemento superior de la pila, y la declaración if se usa para determinar si el La pila ya existe o si hay un elemento de pila. Si la declaración if se usa para determinar si la pila ya existe o si un elemento existe, y si la declaración if no es verdadera, se generará una excepción

A través del análisis anterior, sabemos que el propósito de la pila _dataBindingContext es pasar el método GetDataItem() que proporciona Container DateItem al método Eval, y el método GetDataItem() es el puente hacia el método Eval. El método Eval calcula automáticamente el Container DataItem porque obtiene el Container DataItem de la pila dataBindingContext. Es por eso que el método Eval puede conocer las propiedades del elemento de datos al que pertenece el nombre del campo, como <#nombre del campo Eval>. También sabemos que Eval es esencialmente la implementación del método Eval en .NET. También sabemos que Eval en .NET es esencialmente una implementación que no renuncia al contenedor DataItem, y el contenedor DataItem no desaparece con el tiempo

Entonces, ¿cómo se construye _dataBindingContext para acomodar el contenedor DataItem? ¿pila?

Siempre que vinculamos un control, pensamos rápidamente en cuál es la última declaración, el ID del control DataBind() Sí, este es el método DataBind(). El método DataBind() tiene otra sobrecarga, DataBind (. bool riseOnDataBinding), que creará una pila para _dataBindingContext.

Utilice el método sobrecargado DataBind(bool flag) para implementar el método dataBindingContext para insertar elementos en la pila o extraerlos de la pila

Implementación de bajo nivel de DataBind(bool riseOnDataBinding)

protected virtual void DataBind (bool riseOnDataBinding) { bool flag = false // Si hay un DataItem presionado en la pila, saldrá más tarde if (this IsBindingContainer) // Para determinar si el control es un contenedor de enlace de datos En realidad, determina si el control es un contenedor de enlace de datos.

IsBindingContainer) // Determinar si el control es un contenedor de enlace de datos es en realidad determinar si la clase de control implementa INamingContainer { bool flag; object obj = DataBinder GetDataItem(this out flag); // Este método determina si ( flag amp; amp; (esta página! = nulo))//Si el control tiene un elemento de datos { esta página PushDataBindingContext(obj);//Empuje el elemento de datos en la pila PushDataBindingContext es una llamada al método Push de _dataBindingContext flag = true } } try { if (raiseOnline).} intente { if (raiseOnDataBinding)//esto es para determinar si se activa el evento DataBinding { this OnDataBinding(EventArgs Empty } this DataBindChildren();//Si el control tiene un DataItem, presione DataItem); a la parte superior de la pila, para que pueda obtener el elemento de datos que acaba de presionar llamando al método Eval o GetDataItem en el control secundario } finalmente {if (bandera)//aparece ahora si se presionó en la pila {esta página PopDataBindingContext();//PopDataBindingContext es una llamada al método Pop de _dataBindingContext} } }}}}Cuando ingresamos el ID de control DataBind(), este método sobrecargado se llamará en la capa inferior para preparar el método _DataItem que contiene DatBindingContext pila, que contiene el DataItem

El evento DataBinding se menciona en el código anterior, entonces, ¿cuándo suele activarse?

1 Programáticamente, cuando llamamos al método DataBind(), el evento DataBinding se activará automáticamente

2 Si estamos usando un control de fuente de datos (por ejemplo, SqlDataSource, etc. ), Cuando vinculamos un control a un control de fuente de datos, este evento se activará automáticamente

Expresiones generales de vinculación de datos Las expresiones de vinculación de datos generalmente se colocan en plantillas para reciclar datos, como Repetidor, Lista de datos y otras plantillas. . Entonces, esto es lo que necesita saber: el repetidor DataList, FormView, etc. deben usar plantillas, de lo contrario no podrán mostrar datos, mientras que GridView, DetailsView, Menu, etc. admiten plantillas. El control Menú GridView DetailsView también admite plantillas, pero no necesitan mostrar datos, mientras que el control TreeView no admite plantillas.

Nota En general, una expresión de enlace de datos no evalúa automáticamente su valor a menos que la página o el control en el que aparece muestre una llamada al método DataBind().

El método DataBind() vincula la fuente de datos al control del servidor llamado y todos sus controles secundarios y analiza y evalúa la expresión de enlace de datos. Analizar y evaluar expresiones de enlace de datos

¡Finalmente, hemos logrado algunos avances! Es hora de volver a mirar la implementación subyacente del método estático DataBinder Eval llamado por el método Eval. Le proporcioné el código fuente de la clase DataBinder para que lo descargue cerca

Eficiencia de implementación II

Con la implementación subyacente del método Eval descrito en la Sección 1, podemos organizar fácilmente el siguientes datos Vincule la expresión y vea si la fuente de datos está vinculada al control del servidor y a todos sus controles secundarios. Eficiencia de implementación ] > > lt; #Container DataItemgt; #((DataRowView)Container DataItem)[ FieldName ] gt; ) gt; Eficiencia El más bajo es <#Eval(field name) gt;lt;#DataBinder Eval(Container DataItem field name) gt De hecho, es injusto organizarlo en el orden anterior debido al uso de estas siete formas de enlace de representación de datos. Los métodos no son exactamente iguales

Los escenarios de uso son aproximadamente los siguientes

|lt;#Eval(FieldName)gt;lt;#DataBinder Eval(Container DataItem). FieldName)gt; Son los más utilizados. Se pueden utilizar como fuente para DataSources relacionados con bases de datos. Además de DataSet DataTable DataView relacionados con bases de datos, también incluyen colecciones ordinarias (como matrices, ArrayList, HashTable, etc.). colecciones generalizadas (como Listlt; Tgt; Dictionarylt; Tkey, Tvalue, etc.)

Tenga en cuenta que siempre son intercambiables, al menos por ahora, siempre que pueda usar el método Eval, puede usar Método DataBinder Eval. En términos de implementación subyacente, el método Eval es ligeramente menos eficiente que el método DataBinder Eval, porque el método Eval necesita llamar al método GetDataItem (), pero finalmente a través de DataBinder, mientras que el método Eval. utiliza tecnología de reflexión para llamar al método Eval según el nombre.

El método Eval utiliza tecnología de reflexión para calcular el valor de la expresión buscando la propiedad por nombre, por lo que tendrá un impacto significativo en el rendimiento

#((DataRowView; )Container DataItem)[nombre del campo] gt;

Solo se puede utilizar cuando la fuente de datos es un Dataset DatTable DataView relacionado con la base de datos. Dataset DatTable DataView Estas fuentes de datos implementan la interfaz IListSource. De hecho, en términos de la naturaleza de la implementación subyacente, es similar al miembro <#((Type) Container DataItem)>lishixinzhi/Article/program /net/201311/11866