实体框架查询中的多个联接
本文关键字:框架 查询 实体 | 更新日期: 2023-09-27 18:27:15
长期潜伏者,首次发布。我过去在这里找到了一些好的答案,所以我想我会来这里看看是否能得到一些帮助!
我是Linq的新手,我正在为我的对象使用实体框架。我的项目中有一个.edmx文件。
首先,我从VS2010附带的示例页面中导入了using System.Linq.Dynamic类,因此我可以将其添加到我的页面中:
使用System.Linq.Dynamic;
问题是,我认为我的加入效果不好。
这是我当前的代码:
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();
}
}
我如何编写它,使它像在普通SQL中那样工作?
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
我需要保持动态的.Where子句和.Select字段名称,正如你现在看到的问题是,我需要执行u.u.CompanyName来返回u.CompanyName字段,因为它在我的联接中出现了两次。
我已经在谷歌上搜索了一段时间,但还没有骰子。
非常感谢您的帮助!
编辑-这是我当前的查询。它很有效,但看起来有点像噩梦。
请耐心等待。如果可以的话,我想把所有的东西都包括在这里,即使有点多。
动态列选择对我来说是必须的。否则,我还不如坚持使用我的表适配器和存储的proc。能够将我的查询减少到返回更少的数据是我的目标之一。如果有人能提出改进建议,我会洗耳恭听吗?
我找不到一种方法来停止选择子项的联接,在SQL中,当我联接时,我只需要通过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();
}
}
这就是SQL在后台运行的内容:
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
答案不多,但建议。首先,去抓LinqPad。在进行查询调优时,这是非常宝贵的。其次,我敢打赌,使用.Join.Linq2Entities会得到一个巨大的查询,它有一个讨厌的习惯,每次执行联接时都会创建投影(子查询)。我会花一些时间在LinqPad和我的查询上,直到我得到我想要的查询。