Monday, August 15, 2011

Linq2EF pitfall: Using Length property causes System.NotSupportedException

ArrayLength is not supported in LINQ to Entities

I spent the last half of previous friday banging my head against the wall over a System.NotSupportedException being thrown by Entity Framework 4.0. Now this might be related to the very fact that it was friday and my mind had already started drifting elsewhere, but I wasn't even close to finding the source of the problem. The exception messages sounded "The LINQ expression node type 'ArrayLength' is not supported in LINQ to Entities". When I saw 'ArrayLength' mentioned there, and stepping through the code in debug mode seeing that it failed in the foreach statement, I assumed the query went OK but Entity Framework was unable to traverse the result set. This was wrong.

You cannot use the .Length property of a VARBINARY field in the where clause of an Entity Framework query.1)

Now this may not come as a surprise to you, unless you've used Linq2SQL. You can there.

This problem is solved by rewriting the Length check to use the EF static method SqlFunctions.DataLength instead. This will result in EF producing a TSQL statement where the TSQL function DataLength is used on the property in question. This is incidentally what Linq2SQL does behind the scenes as well, without having to be told explicitlty (I found out that by using LinqPad).

1) This probably goes for the select clause as well, and for all fields having an intrinsic lenght/size property, but this is what I have tested in specific.

A small example - the wrong way

                var results = db.Customers.Where(p => p.PicutereBlob.Length > 0);
				foreach (var customer in results) { /* Do something */ }
Now the exception occurs on line 2 - one of the reasons for my confusion last friday. But of course, that's how Linq and Entity Framework operates.

A small example - the right way

                var results = db.Customers.Where(p => SqlFunctions.DataLength(p.PicutereBlob) > 0);

...or in plain Linq syntax:

from p in Customers
SqlFunctions.DataLength(p.PicutereBlob) > 0
select p

Resulting SQL query:

SELECT 
[Extent1].[PictureBlob] AS [PictureBlob], 
FROM [dbo].[Customers] AS [Extent1]
WHERE ( CAST(DATALENGTH([Extent1].[PictureBlob]) AS int)) > 0
This will be the statement given that PictureBlob is the only field in the table Customers.

By the way, This output is semi-directly copy-pasted from the console output while using the brilliant library provided by Jaroslaw Kowalski at his MSDN blog. This gives you the power to monitor all generated SQL queries from the client. A feature which again, Linq2SQL has by default. This in turn leads to the discussion of why we use Entity Framework in the first place, but I'm not going to delve into that hornet nest.


3 comments:


  1. شركة نقل عفش
    اهم شركات مكافحة حشرات بالخبر كذلك معرض اهم شركة مكافحة حشرات بالدمام والخبر والجبيل والخبر والاحساء والقطيف كذلك شركة رش حشرات بالدمام ومكافحة الحشرات بالخبر
    شركة مكافحة حشرات بالدمام
    شركة تنظيف خزانات بجدة الجوهرة من افضل شركات تنظيف الخزانات بجدة حيث ان تنظيف خزانات بجدة يحتاج الى مهارة فى كيفية غسيل وتنظيف الخزانات الكبيرة والصغيرة بجدة على ايدى متخصصين فى تنظيف الخزانات بجدة
    شركة تنظيف خزانات بجدة
    شركة كشف تسربات المياه بالدمام
    شركة نقل عفش واثاث

    ReplyDelete


  2. شركة نقل عفش بالرياض وجدة والدمام والخبر والجبيل اولقطيف والاحساء والرياض وجدة ومكة المدينة المنورة والخرج والطائف وخميس مشيط وبجدة افضل شركة نقل عفش بجدة نعرضها مجموعة الفا لنقل العفش بمكة والخرج والقصيم والطائف وتبوك وخميس مشيط ونجران وجيزان وبريدة والمدينة المنورة وينبع افضل شركات نقل الاثاث بالجبيل والطائف وخميس مشيط وبريدة وعنيزو وابها ونجران المدينة وينبع تبوك والقصيم الخرج حفر الباطن والظهران
    شركة نقل عفش بجدة
    شركة نقل عفش بالمدينة المنورة
    شركة نقل اثاث بالرياض
    شركة نقل عفش بالدمام

    ReplyDelete