LINQ to Entities Hakkında Bilinen Sorunlar ve Dikkat Edilmesi Gerekenler

Bu bölümde LINQ to Entities sorgularıyla ilgili bilinen sorunlar hakkında bilgi sağlanır.

Önbelleğe Alınamayan LINQ Sorguları

.NET Framework 4.5'den başlayarak LINQ to Entities sorguları otomatik olarak önbelleğe alınır. Ancak, işleci bellek içi koleksiyonlara uygulayan Enumerable.Contains LINQ to Entities sorguları otomatik olarak önbelleğe alınmaz. Ayrıca derlenmiş LINQ sorgularında bellek içi koleksiyonların parametreleştirilmesine izin verilmez.

Kayıp Sipariş Bilgileri

Sütunları anonim bir türe yansıtmak, "80" uyumluluk düzeyine ayarlanmış bir SQL Server 2005 veritabanında yürütülen bazı sorgularda sıralama bilgilerinin kaybolmasına neden olur. Aşağıdaki örnekte gösterildiği gibi, sıralama ölçütü listesindeki bir sütun adı seçicideki bir sütun adıyla eşleştiğinde bu durum oluşur:

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);
}
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

İşaretsiz Tamsayılar Desteklenmiyor

Entity Framework imzasız tamsayıları desteklemediğinden, LINQ to Entities sorgusunda işaretsiz bir tamsayı türü belirtilmesi desteklenmez. İmzasız bir tamsayı belirtirseniz, aşağıdaki örnekte gösterildiği gibi sorgu ifadesi çevirisi sırasında bir ArgumentException özel durum oluşturulur. Bu örnek, 48000 kimliğine sahip bir siparişi sorgular.

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);
    }
}
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

Tür Dönüştürme Hataları

Visual Basic'te bir özellik, işlevi kullanılarak 1 değerine sahip bir SQL Server bit türü sütununa CByte eşlendiğinde, "Aritmetik taşma hatası" iletisiyle bir SqlException oluşturulur. Aşağıdaki örnek AdventureWorks örnek veritabanındaki sütunu sorgular Product.MakeFlag ve sorgu sonuçları yinelendiğinde bir özel durum oluşturulur.

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

Skaler Olmayan Değişkenlere Başvurma Desteklenmiyor

Sorguda varlık gibi skaler olmayan değişkenlere başvuruda bulunmak desteklenmez. Böyle bir sorgu yürütürken, NotSupportedException "türünde EntityTypesabit bir değer oluşturulamıyor" iletisini içeren bir özel durum oluşturulur. Bu bağlamda yalnızca ilkel türler ('Int32, String ve Guid' gibi) desteklenir."

Not

Bir skaler değişken koleksiyonuna başvuruda bulunmak desteklenir.

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);
    }
}
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

sql server 2000 ile iç içe sorguları başarısız olabilir

SQL Server 2000 ile LINQ to Entities sorguları, üç veya daha fazla düzey derinliğinde iç içe Transact-SQL sorguları üretirse başarısız olabilir.

Anonim Türe Yansıtma

üzerinde yöntemini ObjectQuery<T> kullanarak Include ilgili nesneleri dahil etmek için ilk sorgu yolunuzu tanımlar ve sonra döndürülen nesneleri anonim bir türe yansıtmak için LINQ kullanırsanız, include yönteminde belirtilen nesneler sorgu sonuçlarına dahil değildir.

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.");
    }
}
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

İlgili nesneleri almak için döndürülen türleri anonim bir türe yansıtmayın.

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.");
    }
}
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

Ayrıca bkz.