2

I have an Entity Framework 4 model in my application. I need it to generate the following SQL:

SELECT *
FROM       Reads            AS R
INNER JOIN Images           AS I ON R.ReadId = I.ReadId AND I.ImageTypeId = 2
LEFT OUTER JOIN Alarms      AS A ON R.ReadId = A.ReadId AND A.DomainId IN (103,102,101,2,1,12) AND A.i_active = 1
LEFT OUTER JOIN ListDetails AS L ON L.ListDetailId = A.ListDetailId
WHERE R.i_active = 1

Here's what I have now for this query in my code:

var items = from read  in query
            join plate in context.Images      on read.ReadId        equals plate.ReadId
            join temp1 in context.Alarms      on read.ReadId        equals temp1.ReadId       into alarms  from alarm in  alarms.DefaultIfEmpty()
            join temp2 in context.ListDetails on alarm.ListDetailId equals temp2.ListDetailId into entries from entry in entries.DefaultIfEmpty()
            where plate.ImageTypeId == 2 && plate.IActive == 1
            select new { read, plate, alarm, entry.OfficerNotes };

How do I modify the Entity Framework query to get the SQL query I need?

0

1 Answer 1

2

For Left Joins - I suggest using a from with a where instead of join, I find it makes it cleaner

For Inner Joins with multiple join conditions - you need to join on two matching anonymous types, or use a from with where conditions

For x IN list, you need to specify your list outside the query and use the Any method or Contains method

List<int> domainIds = new List<int>() { 103,102,101,2,1,12 };

    var items = from read  in query
                join plate in context.Images
                on new { read.ReadId, ImageTypeId = 2 } equals new { plate.ReadId, plate.ImageTypeId }
                from alarm in context.Alarms
                                     .Where(x => x.IActive == 1)
                                     .Where(x => domainIds.Any(y => y == x.DomainId))
                                     .Where(x => read.ReadId == x.ReadId)
                                     .DefaultIfEmpty()
                from entry in context.ListDetails 
                                     .Where(x => alarm.ListDetailId == x.ListDetailId)
                                     .DefaultIfEmpty()
                select new { read, plate, alarm, entry.OfficerNotes };
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! I made those changes to the code and they work perfectly! However, I did use Contains on the domain ID test.
I would recommend to use Contains instead of Any. Contains produces clean IN statement, while Any produces awful EXISTS (SELECT 1 AS [C1] FROM (... SELECT 103 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable1] UNION ALL SELECT 102 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable2]) AS [UnionAll1] WHERE [UnionAll1].[C1] = [Extent3].[DomainId])
@Ruslan - In this case, you are probably correct - Contains is better. I like using Any, because it allows for more complex conditions

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.