2016-08-14 20 views
5

Bu sorgunun linq sorgu sözdizimini kullanarak yöntem tabanlı bir sözdizimine dönüştürmeye çalışıyorum.Sorgu sözdizimini kullanmadan Entity Framework'te sol dış birleştirme nasıl yapılır?

var products = context.Products 
    .Join(inner: context.TopSellings.DefaultIfEmpty(), 
      outerKeySelector: c => c.Id, innerKeySelector: y => y.Id, 
      resultSelector: (j, k) => new { Name = j.Name, Rating = k.Rating == null ? 0 : k.Rating }) 
    .OrderByDescending(p => p.Rating); 

ve:

{SELECT 
    [Project1].[Id] AS [Id], 
    [Project1].[Name] AS [Name], 
    [Project1].[C1] AS [C1] 
    FROM (SELECT 
     [Extent1].[Id] AS [Id], 
     [Extent1].[Name] AS [Name], 
     CASE WHEN ([Extent2].[Rating] IS NULL) THEN 0 ELSE [Extent2].[Rating] END AS [C1], 
     [Extent2].[Rating] AS [Rating] 
     FROM [dbo].[Products] AS [Extent1] 
     LEFT OUTER JOIN [dbo].[TopSellings] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id] 
    ) AS [Project1] 
    ORDER BY [Project1].[Rating] DESC} 

Bugüne kadar ne denedim böyle bir şeydir:

var products = from p in context.Products 
       join t in context.TopSellings 
       on p.Id equals t.Id into g 
       from tps in g.DefaultIfEmpty() 
       orderby tps.Rating descending 
       select new 
       { 
        Name = p.Name, 
        Rating = tps.Rating == null ? 0 : tps.Rating 
       }; 

sorgu yukarıda bu sql sorgusu üretir: Burada

sorgu var Bu, farklı bir sql sorgusu üretir (Hangi veriyi bei olduğu konusunda elbette farklı bir anlamı vardır) Programda kullanılan ng):

{SELECT 
    [Project1].[Id] AS [Id], 
    [Project1].[Name] AS [Name], 
    [Project1].[C1] AS [C1] 
    FROM (SELECT 
     [Extent1].[Id] AS [Id], 
     [Extent1].[Name] AS [Name], 
     CASE WHEN ([Join1].[Rating] IS NULL) THEN 0 ELSE [Join1].[Rating] END AS [C1] 
     FROM [dbo].[Products] AS [Extent1] 
     INNER JOIN (SELECT [Extent2].[Id] AS [Id], [Extent2].[Rating] AS [Rating] 
      FROM (SELECT 1 AS X) AS [SingleRowTable1] 
      LEFT OUTER JOIN [dbo].[TopSellings] AS [Extent2] ON 1 = 1) AS [Join1] ON [Extent1].[Id] = [Join1].[Id] 
    ) AS [Project1] 
    ORDER BY [Project1].[C1] DESC} 

Cevabınız çok yardımcı olacaktır ve çok teşekkür ederiz!

+0

Bu tür dönüşümler bana anlamsız, ama yine de, eşdeğer yöntem sözdizimi GroupJoin' SelectMany' 'tarafından takip' kullanmak istiyorsunuz, oradan kendiniz yapabilirsiniz umuyoruz. –

+0

Bkz. Msdn: https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b – jdweng

+0

@IvanStoev, salt öğrenme amaçlıdır. –

cevap

5

Genellikle sorgunun Expression özelliğine erişerek herhangi bir sorgu ifadesinden kullanılan ifadeyi tam olarak alabilirsiniz. O zaman sadece bu ifadeyi analiz edip çoğaltır.

var expr = products.Expression; 

Diğer taraftan, sorgu sözdizimini kullanan tüm ifadeler düz bir ileri dönüşüme sahiptir. Maddenin into parçası ile birleşimi, bir GroupJoin()'a karşılık gelirken, fazladan from tümcecikleri SelectMany()'a karşılık gelir. Bu eşdeğer sorguyu üretmelidir:

var products = context.Products.GroupJoin(context.TopSellings, 
     p => p.Id, t => t.Id, (p, g) => new { p, g }) 
    .SelectMany(x => x.g.DefaultIfEmpty(), 
     (x, tps) => new { x.p, x.g, tps }) 
    .OrderByDescending(x => x.tps.Rating) 
    .Select(x => new { x.p.Name, Rating = x.tps.Rating == null ? 0 : x.tps.Rating }); 

Ama artık kullanılır değişkenleri kesme bazı fazlalıkları uzaklaştırır ve bazı yararlı operatörler de yararlanabilir. Sadece üretilen gerçek sorguyu etkileyebileceğinin farkında olun, böylece tam olarak eşleşmez, ancak yeterince yakın olmalıdır.

var products = context.Products.GroupJoin(context.TopSellings, 
    p => p.Id, t => t.Id, 
    (p, g) => g.DefaultIfEmpty() 
     .OrderByDescending(tps => tps.Rating) 
     .Select(tps => new { p.Name, Rating = tps.Rating ?? 0 }) 
); 
+0

wow, tam olarak bu! teşekkürler, btw, bahsettiğiniz o 'ifade' özelliği hakkında iyi bir ipucu, birazcık "şifreli" olsa da ... dikkatlice analiz ederseniz ... mantıklı! Teşekkürler. –

-2
using EF 

AAWSADBEntitiesContext = new AAWSA_DBEntitiesContext(); 
     // .Where(pp1 => ((zemechaObj.DriverId == pp1.DriverId) || (zemechaObj.DriverId == pp1.DriverId))) 
     var myresult =(from zemechaObj in AAWSADBEntitiesContext.WaterSupplyForwardedZemechResourses 
         where zemechaObj.CompanyId == companyId && zemechaObj.Status == WaterSupplyServiceRequest.Shared.ToString() 

         from driverObj in AAWSADBEntitiesContext.tbl_Driver 
           .Where(driver => ((zemechaObj.DriverId == driver.DriverId))) 
           .DefaultIfEmpty() 
          //fromBranch 
         from fromBranch in AAWSADBEntitiesContext.tbl_CompanyRegistrationInformation 
           .Where(fromB => ((zemechaObj.FromBranchId == fromB.CompanyId))) 

          //toBranch 
         from toBranch in AAWSADBEntitiesContext.tbl_CompanyRegistrationInformation 
           .Where(toB => ((zemechaObj.ToBranchId == toB.CompanyId))) 
           //vehicle 
          from vehicleObj in AAWSADBEntitiesContext.tbl_Vehicle 
           .Where(veh => ((zemechaObj.VehicleId == veh.VehicleId))) 
            .DefaultIfEmpty() 
           //assistant one 
         from DriverAssistantOneObj in AAWSADBEntitiesContext.tbl_DriverAssistant 
           .Where(driverAssistOne => ((zemechaObj.DriverAssitantFirstID == driverAssistOne.DriverAssistantId))) 
           .DefaultIfEmpty() 
          //assistant one 
         from DriverAssistantTwoObj in AAWSADBEntitiesContext.tbl_DriverAssistant 
           .Where(driverAssistTwo=> ((zemechaObj.DriverAssitantSecondID == driverAssistTwo.DriverAssistantId))) 
           .DefaultIfEmpty() 
          select new BranchResourceForZemechaEntities() 
          { 
           ForwaredResourseID = zemechaObj.ForwaredResourseID, 
           ServiceStartDate = zemechaObj.ServiceStartDate.ToString(), 
           ServiceEndDate = zemechaObj.ServiceEndDate.ToString(), 
           ForwaredDate = zemechaObj.ForwaredDate.ToString(), 
           Status = zemechaObj.Status, 
           Comment = zemechaObj.Comment, 
           //from Branch 
           FromBranchName = fromBranch.CompanyName, 
           //To Branch 
           ToBranchName = toBranch.CompanyName, 
           VehicleId = zemechaObj.VehicleId, 
           //Vehicle info 
           PlateNumber = vehicleObj.PlateNumber+" ", 
           DriverId = zemechaObj.DriverId, 
           //Driver Full Name 
           DriverFullName = driverObj.FirstName + " " + driverObj.MiddleName + " " + driverObj.LastName, 
           // Driver Assitant one Full Name 
           DriverAssitantFirstID = zemechaObj.DriverAssitantFirstID, 
           DriverAssistantOneFullName = DriverAssistantOneObj.FirstName + " " + DriverAssistantOneObj.MiddleName + " " + DriverAssistantOneObj.LastName, 
           // Driver Assitant Two Full Name 
           DriverAssitantSecondID = zemechaObj.DriverAssitantSecondID, 
           DriverAssistantTwoFullName = DriverAssistantTwoObj.FirstName + " " + DriverAssistantTwoObj.MiddleName + " " + DriverAssistantTwoObj.LastName, 

           CompanyId = zemechaObj.CompanyId, 
           FromBranchId = zemechaObj.FromBranchId, 
           ToBranchId = zemechaObj.ToBranchId, 
           BrLoggedUserId = zemechaObj.BrLoggedUserId.ToString() 

          }).ToList(); 
     return myresult.ToList<BranchResourceForZemechaEntities>(); 
+0

Lütfen sadece bir kod bloğu dökmeyin - bunun yerine çözümünüzü açıklayın. – Moritz

İlgili konular