Problemas conocidos y consideraciones en LINQ to Entities

En esta sección se ofrece información sobre los problemas conocidos relacionados con consultas de LINQ to Entities .

  • Pérdida de información de ordenación

  • Enteros sin signo no admitidos

  • Errores de la conversión de tipos

  • Referencia a variables no escalares no admitida

  • Se puede producir un error en consultas anidadas con SQL Server 2000

  • Proyectar a un tipo anónimo

Pérdida de información de ordenación

La proyección de columnas en un tipo anónimo provocará la pérdida de información de ordenación en algunas consultas que se ejecuten en un conjunto de base de datos de SQL Server 2005 con un nivel de la compatibilidad de "80". Esto se produce cuando un nombre de columna en la lista ORDER BY coincide con un nombre de columna en el selector, como se muestra en el ejemplo siguiente:

Using context As New AdventureWorksEntities()
    ' Ordering information is lost when executed against a SQL Server 2005
    ' database running with a compatibility level of "80".
    Dim results = context.Contacts.SelectMany(Function(c) c.SalesOrderHeaders) _
        .OrderBy(Function(c) c.SalesOrderDetails.Count) _
        .Select(Function(c) New With {c.SalesOrderDetails.Count})

    For Each result In results
        Console.WriteLine(result.Count)
    Next
End Using
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    // Ordering information is lost when executed against a SQL Server 2005
    // database running with a compatibility level of "80".
    var results = context.Contacts.SelectMany(c => c.SalesOrderHeaders)
        .OrderBy(c => c.SalesOrderDetails.Count)
        .Select(c => new { c.SalesOrderDetails.Count });

    foreach (var result in results)
        Console.WriteLine(result.Count);

}

Enteros sin signo no admitidos

La especificación de un tipo entero sin signo en una consulta de LINQ to Entities no se admite porque Entity Framework no admite enteros sin signo. Si se especifica un entero sin signo, se producirá una excepción ArgumentException se durante la conversión de la expresión de consulta, como se muestra en el ejemplo siguiente. En este ejemplo se consulta un pedido cuyo número de identificación (Id.) es 48000.

Using context As New AdventureWorksEntities()
    Dim saleId As UInteger = UInt32.Parse("48000")

    Dim query = _
        From sale In context.SalesOrderDetails _
        Where sale.SalesOrderID = saleId _
        Select sale

    Try
        ' NotSupportedException exception is thrown here.
        For Each order As SalesOrderDetail In query
            Console.WriteLine("SalesOrderID: " & order.SalesOrderID)
        Next
    Catch ex As NotSupportedException
        Console.WriteLine("Exception: " + ex.Message)
    End Try
End Using
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    uint s = UInt32.Parse("48000");

    IQueryable<SalesOrderDetail> query = from sale in context.SalesOrderDetails
                                         where sale.SalesOrderID == s
                                         select sale;

    // NotSupportedException exception is thrown here.
    try
    {
        foreach (SalesOrderDetail order in query)
            Console.WriteLine("SalesOrderID: " + order.SalesOrderID);
    }
    catch (NotSupportedException ex)
    {
        Console.WriteLine("Exception: {0}", ex.Message);
    }
}

Errores de la conversión de tipos

En Visual Basic, cuando se asigna una propiedad a una columna de tipo bit de SQL Server con un valor de 1 utilizando la función CByte, se produce una excepción SqlException con el mensaje "Error de desbordamiento aritmético". En el ejemplo siguiente se consulta la columna Product.MakeFlag en la base de datos de ejemplo AdventureWorks y se produce una excepción cuando tiene lugar una iteración en los resultados de la consulta.

Using context As New AdventureWorksEntities()
    Dim productsList = _
        From product In context.Products _
        Select CByte(product.MakeFlag)

    ' Throws an SqlException exception with a "Arithmetic overflow error 
    ' for data type tinyint" message when a value of 1 is iterated over.
    For Each makeFlag In productsList
        Console.WriteLine(makeFlag)
    Next
End Using

Referencia a variables no escalares no admitida

En una consulta no se puede hacer referencia a variables no escalares, tales como una entidad. Cuando este tipo de consulta se ejecuta, se genera una excepción NotSupportedException con un mensaje que indica "No se puede crear un valor constante de tipo EntityType". Solo los tipos primitivos ('como Int32, String y Guid') se admiten en este contexto.".

Bb896317.note(es-es,VS.100).gifNota:
Permite hacer referencia a una colección de variables escalares.

Using context As New AdventureWorksEntities()

    Dim contact As Contact = context.Contacts.FirstOrDefault()

    ' Referencing a non-scalar closure in a query will
    ' throw an exception when the query is executed.
    Dim contacts = From c In context.Contacts _
                   Where c.Equals(contact) _
                   Select c.LastName

    Try
        For Each name As String In contacts
            Console.WriteLine("Name: ", name)
        Next

    Catch ex As Exception
        Console.WriteLine(ex.Message)
    End Try

End Using
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    Contact contact = context.Contacts.FirstOrDefault();

    // Referencing a non-scalar closure in a query will
    // throw an exception when the query is executed.
    IQueryable<string> contacts = from c in context.Contacts
        where c == contact
        select c.LastName;

    try
    {
        foreach (string name in contacts)
        {
            Console.WriteLine("Name: ", name);
        }
    }
    catch (NotSupportedException ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Se puede producir un error en consultas anidadas con SQL Server 2000

Con SQL Server 2000, se puede producir un error en consultas LINQ to Entities si se generan consultas Transact-SQL anidadas con tres o más niveles de profundidad.

Proyectar a un tipo anónimo

Si define su ruta de acceso de consultas inicial para incluir objetos relacionados utilizando el método Include sobre ObjectQuery y, a continuación, utiliza LINQ para proyectar los objetos devueltos sobre un tipo anónimo, los objetos especificados en el método de inclusión no se incluyen en los resultados de la consulta.

Using context As New AdventureWorksEntities()
    Dim resultWithoutRelatedObjects = context.Contacts. _
        Include("SalesOrderHeaders"). _
        Select(Function(c) New With {c}).FirstOrDefault()
    If resultWithoutRelatedObjects.c.SalesOrderHeaders.Count = 0 Then
        Console.WriteLine("No orders are included.")
    End If
End Using
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var resultWithoutRelatedObjects =
        context.Contacts.Include("SalesOrderHeaders").Select(c => new { c }).FirstOrDefault();
    if (resultWithoutRelatedObjects.c.SalesOrderHeaders.Count == 0)
    {
        Console.WriteLine("No orders are included.");
    }
}

Para obtener objetos relacionados, no proyecte los tipos devueltos sobre un tipo anónimo.

Using context As New AdventureWorksEntities()
    Dim resultWithRelatedObjects = context.Contacts. _
        Include("SalesOrderHeaders"). _
        Select(Function(c) c).FirstOrDefault()
    If resultWithRelatedObjects.SalesOrderHeaders.Count <> 0 Then
        Console.WriteLine("Orders are included.")
    End If
End Using
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var resultWithRelatedObjects =
        context.Contacts.Include("SalesOrderHeaders").Select(c => c).FirstOrDefault();
    if (resultWithRelatedObjects.SalesOrderHeaders.Count != 0)
    {
        Console.WriteLine("Orders are included.");
    }
}

Vea también

Conceptos

LINQ to Entities