【发布时间】:2012-03-08 17:25:54
【问题描述】:
长期潜伏者,第一次海报。过去我在这里找到了一些很好的答案,所以我想我会来这里看看我能不能得到一点帮助!
我对 Linq 很陌生,我正在为我的对象使用实体框架。我的项目中有一个 .edmx 文件。
首先,我从 VS 2010 附带的示例页面中导入了 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 字段名称,您现在可以看到的问题是我需要执行 uuCompanyName 来取回 u.CompanyName 字段,因为它在我的联接中两次。
我已经在谷歌上搜索了一段时间,但还没有骰子。
非常感谢任何帮助!
编辑 - 这是我当前的查询。它有效,但看起来有点像噩梦。
忍受我。如果可以的话,我想把所有东西都包括在这里,即使它有点多。
动态列选择对我来说是必须的。否则我还不如坚持使用我的表适配器和存储过程。能够减少我的查询以返回更少的数据是我的目标之一。如果有人可以提出改进建议,我会全力以赴?
我无法找到一种方法来停止将我的联接选择到子项中,在 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
【问题讨论】:
-
你说我不认为我的加入运行良好是什么意思?它是否返回正确的记录?慢吗?看到生成的sql了吗?
-
一般我这样加入的时候,可以用表的别名返回我想要的记录。 f.ex 如果我像在我的 SQL 语句中那样调用它,我可以使用 u.Field1、u.Field2 从我别名为 u 的用户表中拉回记录。如果我像这样使用我的查询,我必须用 u.u.FieldName 拉回该字段。这对我来说似乎不对!请参阅我的 .OrderBy 声明以了解我的意思。
-
如果它有效并且不慢,我不明白你在找什么。似乎没有实际问题
-
通常我会完全同意你的看法,但它现在的工作方式仍然不适合我,并且加入几乎是我遇到的唯一问题。动态的 Where/Order/Select 东西都运行良好。如果我采用上述方法并添加另一个连接,我会突然需要识别我的列,如 u.u.u.FieldName,有点 OTT,我相信你会同意!
-
通过在 Join 1 中声明列,然后在 Join 2 中再次声明它的工作原理。但是,如果您检查上面的编辑,您会发现它有点笨拙。
标签: c# linq entity-framework join linq-to-entities