Entity Framework: Consejos y trucos, Parte 3

Este artículo continúa una serie de publicaciones sobre las situaciones no triviales de Entity Framework que enfrentan nuestros usuarios.

En este artículo, abordamos los siguientes temas:

1. ¿Por qué Oracle crea una excepción sobre demasiadas sesiones locales involucradas en transacciones globales al usar TransactionScope?

Problema:

Ejecuté el siguiente código de prueba:

public void TestMaxNumberOfObjectContetxtInTransactionScope()
{
   using (TransactionScope ts = new 
      TransactionScope(TransactionScopeOption.Required, 
      IsolationLevel.ReadCommitted))
      {
          for (int i = 0; i < 50; i++)
          {
              using (TestObjectContext context = new TestObjectContext())
             {
                 TestData newTestData = TestData.CreateTestData(id);
                 newTestData.Description = description;
                 context.AddToTestDataEntity(newTestData);
                 context.SaveChanges();
             }
           }
           ts.Complete();
       }
}

y falló después de 32 iteraciones. Recibo el error "ORA-02045: demasiadas sesiones locales involucradas
transacción global”. Otra cosa sorprendente es que en el modo Directo todo funciona a la perfección.
¿Podría explicar el comportamiento?

Solución:

El número máximo de sucursales en una transacción distribuida de Oracle es 32. Usamos transacciones distribuidas de Oracle en nuestro código que implementa el soporte de TransactionScope. Entonces, una vez que el número de transacciones en un área excede ese número, existe este error. La razón por la que funciona el modo directo es que no admite transacciones distribuidas (se utilizan transacciones locales). Por lo tanto, una solución consiste en usar TransactionScope con menos ramas de transacciones. En la mayoría de los escenarios, es suficiente usar una transacción local, como en el siguiente ejemplo:

context.Connection.Open();
DEPT department = context.DEPT.Where(d => d.DEPTNO == 10).First();
department.LOC = "TEST";

using (System.Data.Common.DbTransaction transaction = 
   context.Connection.BeginTransaction()) {
   context.SaveChanges();
   department.DNAME = "TEST";
   context.SaveChanges();

   if (flag)
      transaction.Commit();
   else
      transaction.Rollback();
 }

Nota: Comenzando con la última versión de dotConnect para Oracle, estamos abordando este problema con soporte publicitario para transacciones de una sola fase. Al abrir varias conexiones, solo se utiliza una sesión activa con una transacción local interna. Puede activar esta opción en la barra de conexión configurando el parámetro "Scope Lacal = true".

2. ¿Cómo puedo optimizar consultas SQL utilizando Entity Framework?

Problema:

Si uso SQL nativo, puedo usar fácilmente sugerencias para optimizar MySQL. ¿Puedo usar algo similar cuando uso Entity Framework?

Solución:

Tiene dos alternativas: la primera, para crear en su base de datos una representación que implemente el comportamiento deseado, y la segunda, para crear manualmente una consulta definitoria en el modelo de repositorio y entidades en su modelo conceptual que coincidan con esas consultas definitorias.

En ambos casos, podrá usar sugerencias de MySQL.

3. ¿Cómo puedo realizar la eliminación de objetos en cascada en Entity Framework?

Problema:

¿Realmente necesito eliminar todos los objetos secundarios por separado? ¿Es posible utilizar la eliminación en cascada?

Solución:

Agregue una acción en cascada para todas las asociaciones que desee que estén en cascada. Esta acción debe agregarse en las secciones CSDL y SSDL .edmx Archivo. Aquí hay una parte de ejemplo de CSDL:

<Association Name="CProductCategory">
    <End Type="Self.CProduct" Multiplicity="*" />
       <End Type="Self.CCategory" Multiplicity="0..1*">
          <OnDelete Action="Cascade" />
       </End>
    </End>
</Association>

A continuación se muestra un ejemplo de un SSDL:

<Association Name="CProductCategory">
    <End Role="PRODUCT" Type=Self.Store.CProduct" Multiplicity="0..1" >
       <OnDelete Action="Cascade" />
    </End>
</Association>

Como puede ver, para agregar eliminación en cascada, simplemente defina el siguiente diseño en la parte CSDL o SSDL de su .edmx Archivo:

 <OnDelete Action="Cascade"/>

4. ¿Cómo puedo obtener el valor predeterminado del campo de la base de datos en mi proyecto de Entity Framework?

Problema:

Mi base de datos Oracle tiene una columna varchar2 "MyProperty" que contiene el valor predeterminado. ¿Cómo puedo obtener este valor, por ejemplo, para completar mi cuadro de texto en el formulario de entrada del usuario?

Solución:

Debe realizar una consulta de MetadataWorkspace, por ejemplo, de la siguiente manera:

MetadataWorkspace workspace = context.MetadataWorkspace;
object value = new value();
var item = workspace.GetItems<EntityType>(DataSpace.CSpace).Where
 (i => i.Name == "MyEntity").Single();
value = item.Properties.Where
 (p => p.Name == "MyProperty").Single().DefaultValue;

Esperamos que este material le resulte útil. Por favor dé su opinión y sugerencias en los comentarios al artículo.

Artículos de interés

Subir