Lurker da molto tempo, poster prima volta. Ho trovato alcune buone risposte qui in passato, quindi la figura vorrei venire qui e vedere se posso avere un piccolo aiuto!Più join in query Entity Framework
Sono piuttosto nuovo a Linq e sto utilizzando Entity Framework per il mio oggetto. Ho un file .edmx nel mio progetto.
Prima di tutto ho importato la classe System.Linq.Dynamic utilizzando le pagine di esempio che è venuto con VS 2010, quindi posso aggiungere questo nella mia pagina:
utilizzando System.Linq.Dynamic;
Il problema è che non credo che il mio join funzioni correttamente.
Questo è il mio codice corrente:
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();
}
}
Come posso scriverlo in modo che funziona in questo modo sarebbe in SQL normale?
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
ho bisogno di mantenere le clausole dinamiche .dove e nomi dei campi .SELECT, il problema come si può vedere in questo momento è che ho bisogno di fare uuCompanyName per tornare sul campo u.CompanyName come è nel mio si unisce due volte.
Ho cercato su Google per un po 'di tempo ma non ho ancora trovato i dadi.
Qualsiasi aiuto molto apprezzato!
MODIFICA - questa è la mia domanda corrente. Funziona ma è un po 'un incubo da vedere.
Orso con me. Volevo includere tutto qui se posso anche se è un po 'troppo.
La selezione dinamica delle colonne è un must per me. Altrimenti potrei anche restare con i miei adattatori da tavolo e i proc memorizzati. Essere in grado di ridurre la mia query a restituire meno dati è uno dei miei obiettivi con questo. Se qualcuno può suggerire miglioramenti, sono tutto orecchie?
Non riuscivo a trovare un modo per smettere di selezionare i miei join in elementi secondari, in SQL quando mi unisco devo semplicemente restituire le colonne che voglio tramite la mia istruzione SELECT.
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();
}
}
Questo è ciò che SQL viene eseguito in background:
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
Cosa intendi quando dici * Non penso che il mio join funzioni bene *? Sta restituendo i record corretti? È lento? Hai visto lo sql generato? – Aducci
Normalmente quando mi unisco in questo modo, posso usare il nome alias della tabella per restituire i record che voglio. f.ex se l'ho chiamato come nella mia istruzione SQL posso usare u.Field1, u.Field2 per tirare indietro i record dalla tabella Users che ho aliasato come u. Se utilizzo la mia query in questo modo, devo riportare il campo con u.u.FieldName. Questo non mi sembra giusto! Vedi la mia dichiarazione .OrderBy per vedere cosa intendo. – HungryHippos
Se funziona e non è lento, non capisco cosa stai cercando.Non sembra esserci un problema reale. – Aducci