开发者

Convert SQL to LINQ

开发者 https://www.devze.com 2023-03-22 13:01 出处:网络
I\'m having a hard time with this SQL Query. I need to convert this to LINQ but n o luck so far. Linqer simply fails.

I'm having a hard time with this SQL Query. I need to convert this to LINQ but n o luck so far. Linqer simply fails.

SELECT dbo.County.Name AS 开发者_C百科County,
       dbo.JobBooking.OID AS BookingID,
       dbo.Job.OID AS JobID,
       CASE JobBooking.JobBookingStatusID WHEN 2 THEN 1 ELSE 0 END AS Booked
FROM   dbo.JobBooking RIGHT OUTER JOIN
       ((((dbo.Branch INNER JOIN
       dbo.Job ON dbo.Branch.OID = dbo.Job.BranchID) INNER JOIN
       dbo.AddressInfo ON dbo.Branch.AddressInfoID = dbo.AddressInfo.OID) 
       INNER JOIN
       dbo.City ON dbo.AddressInfo.CityID = dbo.City.OID) INNER JOIN
       dbo.County ON dbo.City.CountyID = dbo.County.OID)
       ON dbo.JobBooking.JobID = dbo.Job.OID

Any help will be greatly appreciated!

Regards.


Because you really wanted your answer in a badly formatted, stupidly long, VB.Net one liner...

Dim results = db.Branches.Join(db.Jobs,
                               Function(n) n.OID,
                               Function(n) n.BranchID,
                               Function(nBranch, nJob) New With {.Branch = nBranch,
                                                                 .Job = nJob}).Join(db.AddressInfos,
                                                                                    Function(n) n.Branch.AddressInfoID,
                                                                                    Function(n) n.OID,
                                                                                    Function(n, nAddressInfo) New With {.Branch = n.Branch,
                                                                                                                        .Job = n.Job,
                                                                                                                        .AddressInfo = nAddressInfo}).Join(db.Cities,
                                                                                                                                                                   Function(n) n.AddressInfo.CityID,
                                                                                                                                                                   Function(n) n.OID,
                                                                                                                                                                   Function(n, nCity) New With {.Branch = n.Branch,
                                                                                                                                                                                                .Job = n.Job,
                                                                                                                                                                                                .AddressInfo = n.AddressInfo,
                                                                                                                                                                                                .City = nCity}).Join(db.Counties,
                                                                                                                                                                                                                     Function(n) n.City.CountyID,
                                                                                                                                                                                                                     Function(n) n.OID,
                                                                                                                                                                                                                     Function(n, nCounty) New With {.Branch = n.Branch,
                                                                                                                                                                                                                                                    .Job = n.Job,
                                                                                                                                                                                                                                                    .AddressInfo = n.AddressInfo,
                                                                                                                                                                                                                                                    .City = n.City,
                                                                                                                                                                                                                                                    .County = nCounty}).GroupJoin(db.JobBookings,
                                                                                                                                                                                                                                                                                  Function(n) n.Job.OID,
                                                                                                                                                                                                                                                                                  Function(n) n.JobID,
                                                                                                                                                                                                                                                                                  Function(n, nJobBooking) New With {.County = n.County.Name,
                                                                                                                                                                                                                                                                                                                     .BookingID = nJobBooking.OID,
                                                                                                                                                                                                                                                                                                                     .JobID = n.Job.OID,
                                                                                                                                                                                                                                                                                                                     .Booked = nJobBooking.DefaultIfEmpty IsNot Nothing AndAlso nJobBooking.DefaultIfEmpty.JobBookingStatusID = 2})

In all honesty, I've no idea if that would work, but I think it should. Now for an answr that hopefully helps. I restructured your SQL to make it easier to translate to Linq, perhaps you could confirm it still works?

SELECT  dbo.County.Name AS County,
        dbo.JobBooking.OID AS BookingID,
        dbo.Job.OID AS JobID,
        CASE JobBooking.JobBookingStatusID WHEN 2 THEN 1 ELSE 0 END AS Booked
FROM    dbo.Branch INNER JOIN dbo.Job ON dbo.Branch.OID = dbo.Job.BranchID
        INNER JOIN dbo.AddressInfo ON dbo.Branch.AddressInfoID = dbo.AddressInfo.OID
        INNER JOIN dbo.City ON dbo.AddressInfo.CityID = dbo.City.OID
        INNER JOIN dbo.County ON dbo.City.CountyID = dbo.County.OID
        LEFT OUTER JOIN dbo.JobBooking  ON dbo.JobBooking.JobID = dbo.Job.OID

Assuming it does indeed still work, break down the query into smaller parts, step by step if needs be. I'm doing it all in lambda (because my primary language is VB and online translators aren't too clever at translating the ol From x In source... syntax.

var branchesAndJobs = db.Branches.Join(db.Jobs, n => n.OID, n => n.BranchID, (n, nJob) => new {Branch = n, Job = nJob})
var branchesJobsAndAddressInfos = branchesAndJobs.Join(db.AddressInfos, n => n.Branch.AddressInfoID, n => n.OID, (n, nAddressInfo) => new {Branch = n.Branch, Job = n.Job, AddressInfo = n.AddressInfo})
// etc through all the normal joins

Then the left outer join (originally a right outer) uses a GroupJoin and DefaultIfEmpty...

var results = allOtherData.GroupJoin(db.JobBookings, n => n.Job.OID, n => n.JobID, (n, nJobBooking) => new {County = n.County.Name, BookingID = nJobBooking.DefaultIfEmpty == null ? null : nJobBooking.DefaultIfEmpty.OID, etc = n.etc})

I'm afraid my syntax is likely to be wildly out, but hopefully close enough for you to work from? Good luck!!


LINQ doesn't support RIGHT OUTER JOINs. You would need to convert this to a left outer instead using the DefaultIfEmpty extension method.

In this case, rather than trying to configure a bunch of joins, either break the query into logical chunks, or change your thinking around to using the object graph instead. Object graphs by default use outer joins rather than inner joins so you don't need DefaultIfEmpty when using the object graph. See if the following helps at all:

Dim query = From branch In Branches
            From job In branch.Jobs
            From booking In job.JobBookings
            Select County = branch.AddressInfo.City.County.Name,
                   BookingID = booking.BookingID,
                   JobID = job.OID,
                   BookedFROM = (booking.JobBookingStatusID = 2)

This isn't exactly the same as I'm returning a boolean for BookedFROM rather than 0/1 integer, but suspect you are wanting a boolean here based on the alias.

Also, realize in your database model, you may get multiple rows because a city may belong to multiple counties which could throw off your expected results.

0

精彩评论

暂无评论...
验证码 换一张
取 消