2012-03-08 23 views
5

Uzun zamandır lurker, ilk kez poster. Geçmişte burada iyi cevaplar buldum, bu yüzden buraya gelip biraz yardım alabilir miyim diye anladım!Varlık Çerçeve sorgusunda birden çok Katılma

Linq için oldukça yeni ve nesneyim için Entity Framework kullanıyorum. Projemde bir .edmx dosyası var. Her şeyden

Önce VS 2010 ile birlikte gelen örnek sayfalarından kullanılarak System.Linq.Dynamic sınıf ithal, bu yüzden benim sayfasına bu ekleyebilirsiniz:

System.Linq.Dynamic kullanarak;

Sorun şu ki, katılımımın iyi çalıştığını sanmıyorum.

Bu benim şimdiki kodudur:

private void FetchData() 
{ 
    using (var Context = new ProjectEntities()) 
    { 
     var Query = 
      Context.Users 
      .Join(Context.UserStats,   // Table to Join 
       u => u.msExchMailboxGuid,  // Column to Join From 
       us => us.MailboxGuid,   // Column to Join To 
       (u, us) => new     // Alias names from Tables 
       { 
        u, 
        us 
       }) 
      .Join(Context.TechContacts,   // Table to Join 
       u => u.u.UserPrincipalName,  // Column to Join From 
       tc => tc.UPN,     // Column to Join To 
       (u, tc) => new     // Alias names from Tables 
       { 
        u = u, 
        tc = tc 
       }) 
       .Where(u => true) 
       .OrderBy("u.u.CompanyName") 
       .Select("New(u.u.CompanyName,tc.UPN,u.us.TotalItemSize)"); 

     // Add Extra Filters 
     if (!(string.IsNullOrWhiteSpace(SearchCompanyNameTextBox.Text))) 
     { 

      Query = Query.Where("u.CompanyName.Contains(@0)", SearchCompanyNameTextBox.Text); 
     } 

     // Set the Record Count 
     GlobalVars.TotalRecords = Query.Count(); 

     // Add Paging 
     Query = Query 
      .Skip(GlobalVars.Skip) 
      .Take(GlobalVars.Take); 

     // GridView Datasource Binding 
     GridViewMailboxes.DataSource = Query; 
     GridViewMailboxes.DataBind(); 
    } 
} 
normal SQL böyle olacağını çalışır böylece

Nasıl yazabilirim ? Ben benim, var olduğu u.CompanyName alanını geri almak için uuCompanyName yapmanız gerektiğidir

SELECT u.Column1, 
u.Column2, 
us.Column1, 
tc.Column1 
FROM Users AS u 
INNER JOIN UserStats AS us 
ON u.msExchMailboxGuid = us.MailboxGuid 
INNER JOIN TechContacts AS tc 
ON u.UserPrincipalName = tc.UPN 

Dinamik .Where maddeleri ve .Select alan adlarını, hemen görebileceğiniz gibi sorunu tutmak için gereken iki kere katılır.

Bunun için bir süredir googled ettik ama henüz bir zar yok.

Herhangi bir yardım çok takdir!

DÜZENLEME - Bu benim geçerli sorgum. İşe yarıyor ama dikkat edilmesi gereken bir kabus.

Benimle kal. Biraz fazla olsa bile, her şeyi buraya dahil etmek istedim.

Dinamik sütun seçimi benim için bir zorunluluktur. Aksi halde, tablo adaptörlerimle ve saklanan pro-kimlerimle yapışabilirim. Sorgumu daha az veriyi geri göndermeye indirgemek, bununla hedeflerimden biri. Herhangi biri geliştirmeleri önerebilirse, ben tüm kulaklarım.

Katılanlarımı subitems olarak seçmek zorunda kalmamanın bir yolu bulamadım, katıldığımda SQL'de SELECT ifademle istediğim sütunları döndürmek zorundayım.

private void FetchData() 
{ 
    using (var Context = new ProjectEntities()) 
    { 
     string Fields = GetDynamicFields(); 

     var Query = 
      Context.Users 
      .Join(Context.UserStats,   // Table to Join 
       u => u.msExchMailboxGuid,  // Column to Join From 
       us => us.MailboxGuid,   // Column to Join To 
       (u, us) => new     // Declare Columns for the next Join 
       { 
        ObjectGuid = u.objectGuid, 
        msExchMailboxGuid = u.msExchMailboxGuid, 
        CompanyName = u.CompanyName, 
        ResellerOU = u.ResellerOU, 
        DisplayName = u.DisplayName, 
        MBXServer = u.MBXServer, 
        MBXSG = u.MBXSG, 
        MBXDB = u.MBXDB, 
        MBXWarningLimit = u.MBXWarningLimit, 
        MBXSendLimit = u.MBXSendLimit, 
        MBXSendReceiveLimit = u.MBXSendReceiveLimit, 
        extensionAttribute10 = u.extensionAttribute10, 
        legacyExchangeDN = u.legacyExchangeDN, 
        UserPrincipalName = u.UserPrincipalName, 
        Mail = u.Mail, 
        lastLogonTimeStamp = u.lastLogonTimestamp, 
        createTimeStamp = u.createTimeStamp, 
        modifyTimeStamp = u.modifyTimeStamp, 
        altRecipient = u.altRecipient, 
        altRecipientBL = u.altRecipientBL, 
        DeletedDate = u.DeletedDate, 
        MailboxGuid = us.MailboxGuid, 
        Date = us.Date, 
        AssociatedItemCount = us.AssociatedItemCount, 
        DeletedItemCount = us.DeletedItemCount, 
        ItemCount = us.ItemCount, 
        LastLoggedOnUserAccount = us.LastLoggedOnUserAccount, 
        LastLogonTime = us.LastLogonTime, 
        StorageLimitStatus = us.StorageLimitStatus, 
        TotalDeletedItemSize = us.TotalDeletedItemSize, 
        TotalItemSize = us.TotalItemSize, 
        MailboxDatabase = us.MailboxDatabase 
       }) 
      .Join(Context.TechContacts,   // Table to Join 
       u => u.UserPrincipalName,  // Column to Join From 
       tc => tc.UPN,     // Column to Join To 
       (u, tc) => new     // Declare Final Column Names 
       { 
        ObjectGuid = u.ObjectGuid, 
        msExchMailboxGuid = u.msExchMailboxGuid, 
        CompanyName = u.CompanyName, 
        ResellerOU = u.ResellerOU, 
        DisplayName = u.DisplayName, 
        MBXServer = u.MBXServer, 
        MBXSG = u.MBXSG, 
        MBXDB = u.MBXDB, 
        MBXWarningLimit = u.MBXWarningLimit, 
        MBXSendLimit = u.MBXSendLimit, 
        MBXSendReceiveLimit = u.MBXSendReceiveLimit, 
        extensionAttribute10 = u.extensionAttribute10, 
        legacyExchangeDN = u.legacyExchangeDN, 
        UserPrincipalName = u.UserPrincipalName, 
        Mail = u.Mail, 
        lastLogonTimeStamp = u.lastLogonTimeStamp, 
        createTimeStamp = u.createTimeStamp, 
        modifyTimeStamp = u.modifyTimeStamp, 
        altRecipient = u.altRecipient, 
        altRecipientBL = u.altRecipientBL, 
        DeletedDate = u.DeletedDate, 
        MailboxGuid = u.MailboxGuid, 
        Date = u.Date, 
        AssociatedItemCount = u.AssociatedItemCount, 
        DeletedItemCount = u.DeletedItemCount, 
        ItemCount = u.ItemCount, 
        LastLoggedOnUserAccount = u.LastLoggedOnUserAccount, 
        LastLogonTime = u.LastLogonTime, 
        StorageLimitStatus = u.StorageLimitStatus, 
        TotalDeletedItemSize = u.TotalDeletedItemSize, 
        TotalItemSize = u.TotalItemSize, 
        MailboxDatabase = u.MailboxDatabase, 
        // New Columns from this join 
        UPN = tc.UPN, 
        Customer_TechContact = tc.Customer_TechContact, 
        Customer_TechContactEmail = tc.Customer_TechContactEmail, 
        Reseller_TechContact = tc.Reseller_TechContact, 
        Reseller_TechContactEmail = tc.Reseller_TechContact, 
        Reseller_Name = tc.Reseller_Name 
       }) 
      .Where(u => true) 
      .OrderBy(GlobalVars.SortColumn + " " + GlobalVars.SortDirection) 
      .Select("New(" + Fields + ")"); 

     // Add Extra Filters 
     if (!(string.IsNullOrWhiteSpace(SearchCompanyNameTextBox.Text))) 
     { 
      Query = Query.Where("CompanyName.StartsWith(@0)", SearchCompanyNameTextBox.Text); 
     } 

     // Set the Record Count 
     GlobalVars.TotalRecords = Query.Count(); 

     // Add Paging 
     Query = Query 
      .Skip(GlobalVars.Skip) 
      .Take(GlobalVars.Take); 

     // GridView Datasource Binding 
     GridViewMailboxes.DataSource = Query; 
     GridViewMailboxes.DataBind(); 
    } 
} 

Bu SQL arka planda çalışır şudur: bir cevap çok ama tavsiyem değil

SELECT TOP (20) 
[Project1].[C1] AS [C1], 
[Project1].[objectGuid] AS [objectGuid], 
[Project1].[msExchMailboxGuid] AS [msExchMailboxGuid], 
[Project1].[CompanyName] AS [CompanyName], 
[Project1].[ResellerOU] AS [ResellerOU], 
[Project1].[DisplayName] AS [DisplayName], 
[Project1].[MBXServer] AS [MBXServer], 
[Project1].[MBXSG] AS [MBXSG], 
[Project1].[MBXDB] AS [MBXDB], 
[Project1].[MBXWarningLimit] AS [MBXWarningLimit], 
[Project1].[MBXSendLimit] AS [MBXSendLimit], 
[Project1].[MBXSendReceiveLimit] AS [MBXSendReceiveLimit], 
[Project1].[extensionAttribute10] AS [extensionAttribute10], 
[Project1].[legacyExchangeDN] AS [legacyExchangeDN], 
[Project1].[UserPrincipalName] AS [UserPrincipalName], 
[Project1].[Mail] AS [Mail], 
[Project1].[lastLogonTimestamp] AS [lastLogonTimestamp], 
[Project1].[createTimeStamp] AS [createTimeStamp], 
[Project1].[modifyTimeStamp] AS [modifyTimeStamp], 
[Project1].[altRecipient] AS [altRecipient], 
[Project1].[altRecipientBL] AS [altRecipientBL], 
[Project1].[DeletedDate] AS [DeletedDate] 
    FROM (SELECT [Project1].[objectGuid] AS [objectGuid], 
     [Project1].[msExchMailboxGuid] AS [msExchMailboxGuid], 
     [Project1].[CompanyName] AS [CompanyName], 
     [Project1].[ResellerOU] AS [ResellerOU], 
     [Project1].[DisplayName] AS [DisplayName], 
     [Project1].[MBXServer] AS [MBXServer], 
     [Project1].[MBXSG] AS [MBXSG], 
     [Project1].[MBXDB] AS [MBXDB], 
     [Project1].[MBXWarningLimit] AS [MBXWarningLimit], 
     [Project1].[MBXSendLimit] AS [MBXSendLimit], 
     [Project1].[MBXSendReceiveLimit] AS [MBXSendReceiveLimit], 
     [Project1].[extensionAttribute10] AS [extensionAttribute10], 
     [Project1].[legacyExchangeDN] AS [legacyExchangeDN], 
     [Project1].[UserPrincipalName] AS [UserPrincipalName], 
     [Project1].[Mail] AS [Mail], 
     [Project1].[lastLogonTimestamp] AS [lastLogonTimestamp], 
     [Project1].[createTimeStamp] AS [createTimeStamp], 
     [Project1].[modifyTimeStamp] AS [modifyTimeStamp], 
     [Project1].[altRecipient] AS [altRecipient], 
     [Project1].[altRecipientBL] AS [altRecipientBL], 
     [Project1].[DeletedDate] AS [DeletedDate], 
     [Project1].[C1] AS [C1], 
     row_number() OVER (ORDER BY [Project1].[CompanyName] ASC) AS [row_number] 
      FROM (SELECT 
       [Extent1].[objectGuid] AS [objectGuid], 
       [Extent1].[msExchMailboxGuid] AS [msExchMailboxGuid], 
       [Extent1].[CompanyName] AS [CompanyName], 
       [Extent1].[ResellerOU] AS [ResellerOU], 
       [Extent1].[DisplayName] AS [DisplayName], 
       [Extent1].[MBXServer] AS [MBXServer], 
       [Extent1].[MBXSG] AS [MBXSG], 
       [Extent1].[MBXDB] AS [MBXDB], 
       [Extent1].[MBXWarningLimit] AS [MBXWarningLimit], 
       [Extent1].[MBXSendLimit] AS [MBXSendLimit], 
       [Extent1].[MBXSendReceiveLimit] AS [MBXSendReceiveLimit], 
       [Extent1].[extensionAttribute10] AS [extensionAttribute10], 
       [Extent1].[legacyExchangeDN] AS [legacyExchangeDN], 
       [Extent1].[UserPrincipalName] AS [UserPrincipalName], 
       [Extent1].[Mail] AS [Mail], 
       [Extent1].[lastLogonTimestamp] AS [lastLogonTimestamp], 
       [Extent1].[createTimeStamp] AS [createTimeStamp], 
       [Extent1].[modifyTimeStamp] AS [modifyTimeStamp], 
       [Extent1].[altRecipient] AS [altRecipient], 
       [Extent1].[altRecipientBL] AS [altRecipientBL], 
       [Extent1].[DeletedDate] AS [DeletedDate], 
       1 AS [C1] 
       FROM [dbo].[Users] AS [Extent1] 
       INNER JOIN [dbo].[UserStats] AS [Extent2] ON [Extent1].[msExchMailboxGuid] = [Extent2].[MailboxGuid] 
       INNER JOIN [dbo].[TechContacts] AS [Extent3] ON [Extent1].[UserPrincipalName] = [Extent3].[UPN] 
      ) AS [Project1] 
    ) AS [Project1] 
WHERE [Project1].[row_number] > 120 
ORDER BY [Project1].[CompanyName] ASC 
+0

Ne zaman demek istediğimi söylüyorsun * Katılımımın iyi çalıştığını düşünmüyorum *? Doğru kayıtları mı döndürüyor? Yavaş mı? Oluşturulan sql'yi gördünüz mü? – Aducci

+0

Normalde bu şekilde katıldığımda, istediğim kayıtları döndürmek için tablonun diğer adını kullanabilirim. f.ex, SQL deyimimde bu şekilde aramış olsaydım, u.Field1, u.Field2'yi u olarak takmadığım Users tablosundan kayıtları geri almak için kullanabilirim. Sorgumu böyle kullanırsam alanı u.u.FieldName ile geri çekmem gerekiyor. Bu bana doğru görünmüyor! Ne demek istediğimi görmek için .OrderBy ifademi görün. – HungryHippos

+0

Çalışıyorsa ve yavaş değilse, ne aradığınızı anlamıyorum.Gerçek bir sorun yok gibi gözüküyor – Aducci

cevap

2

. İlk önce, LinqPad'u yakalayın. Sorgu ayarlaması yaparken, bu paha biçilemez. İkincisi, bahse girerim .Join kullanmanın sonucunda büyük bir sorgu almanızdır. Linq2Entities, her katılımınızda projeksiyon (alt sorgular) oluşturma konusunda kötü bir alışkanlığa sahiptir. İstediğim sorguyu alana kadar LinqPad ve sorgumla biraz kaliteli zaman geçiririm.

+0

teşekkürler, LinqPad ile bir oyun oynayacak ve ne olduğunu göreceksiniz :) – HungryHippos

+0

Oh adam bu sadece daha eğlenceli olur. Şu anda sahip olduğum şeyle OP'imi günceller. – HungryHippos

+0

Tamam, bu yüzden LinqPad ile oynamıştım, ancak bu benim için hiç de kolay değil çünkü otomatik tamamlama gibi harika özellikler olmadığından, yazdığım şeyin gerçekten çalışıp çalışmadığını bilmiyorum. Eğer benim OP'imi kontrol ederseniz, şu anda ne koştuğumu göreceksiniz ama şimdiki TableAdapter ve Stored Proc yöntemlerinden fark edilir derecede daha yavaş. – HungryHippos

İlgili konular