Here’s a simple linq query I executed in Entity framework
db.Responses.FirstOrDefault(r => r.QuestionId.Equals(“1.1.1”) && r.User.Id.Equals(user.Id) && !r.IsDeleted);
Here QuestionId is a varchar datatype column, and db is the context object.
I fired up Entity profiler to see what was happening under the hood and underlying SQL query seem to have a bunch of statement that seemed a bit superfluous
/* 1 */ SELECT TOP (1) *
/* 2 */ FROM [dbo].[Responses] AS [Extent1]
/* 3 */ WHERE ((([Extent1].[QuestionId] = '1.1.1' /* @p__linq__0 */)
/* 4 */ AND (NOT ([Extent1].[QuestionId] IS NULL
/* 5 */ OR '1.1.1' /* @p__linq__0 */ IS NULL)))
/* 6 */ OR (([Extent1].[QuestionId] IS NULL)
/* 7 */ AND ('1.1.1' /* @p__linq__0 */ IS NULL)))
/* 8 */ AND ([Extent1].[UserId] = 1 /* @p__linq__1 */)
/* 9 */ AND (1 /* @p__linq__1 */ IS NOT NULL)
/* 10 */ AND ([Extent1].[IsDeleted] <> cast(1 as bit))
Notice all the extra code in lines 4-7, changing QuestionId to not null simplifies the query as so
/* 1 */ SELECT TOP (1) *
/* 2 */ FROM [dbo].[Responses] AS [Extent1]
/* 3 */ WHERE ([Extent1].[QuestionId] = '1.1.1' /* @p__linq__0 */)
/* 4 */ AND ('1.1.1' /* @p__linq__0 */ IS NOT NULL)
/* 5 */ AND ([Extent1].[UserId] = 1 /* @p__linq__1 */)
/* 6 */ AND (1 /* @p__linq__1 */ IS NOT NULL)
/* 7 */ AND ([Extent1].[IsDeleted] <> cast(1 as bit))
So, the question is why does entity framework put in all that extra code? Why is line 4 & line 6 necessary, the only relevant statements in the where clause are line 3,5 and 7,
I'm attempting to optimize my SQL statements and any thoughts on why entity framework is doing things this way would be helpful. I'm using EF6 with Visual studio 2013.
r.QuestionId == "1.1.1"?