【问题标题】:How to convert this SQL query to Linq如何将此 SQL 查询转换为 Linq
【发布时间】:2015-09-04 14:16:14
【问题描述】:

我有一个现有的 LINQ 查询,它需要两个右连接,我知道如何用 SQL 编写它,但我不确定 LINQ。

这不是关于如何在 linq 中加入的问题。我需要这两个。

考虑以下伪 SQL 查询:

SELECT      [ProjectItem].*
FROM        [ProjectItem]
RIGHT JOIN  [UserCostingItem]
ON          [UserCostingItem].[CostingItemID] 
=           [ProjectItem].[ProjectItemID]
RIGHT JOIN  [UserCostingItemType]
ON          [UserCostingItemType].[CostingItemType]
=           [ProjectItem].[ProjectItemType]
WHERE 
(
    [UserCostingItem].[PrimaryKey] IS NOT NULL
    OR 
    [UserCostingItemType].[PrimaryKey] IS NOT NULL
)

我想获取 Project Item 表中的记录,其中UserCostingItem 表或UserCostingItemType 表中有一条记录。

目前我正在加入一个表,但我需要在两个表上都右加入并仅返回其中一个联接中存在的记录。

这是我到目前为止的代码,它只是在一个表上进行内部连接:

List<PCProjectItem> projectItems = new List<PCProjectItem>();
List<UserCostingItem> userCostingItems = new List<UserCostingItem>();
List<UserCostingItemType> userCostingItemTypes = new List<UserCostingItemType>();

projectItems = PCProjectItem.GetProjectItems(projectID, sageDatabaseID, PCIntegrationOption);
userCostingItems = UserCostingItem.GetUserCostingItems(userID, sageDatabaseID, documentType == null ? string.Empty : documentType.Value.ToString());
userCostingItemTypes = UserCostingItemType.GetUserCostingItemTypes(userID, sageDatabaseID);

//If there are no project items or allocations, return a new list now
if (projectItems.Count == 0 || (userCostingItems.Count == 0 && userCostingItemTypes.Count == 0))
{
     return new List<PCProjectItem>();
}

//Get the project Items the user has access to only
return (from PCProjectItem projectItem in projectItems
        join UserCostingItem userCostingItem in userCostingItems on projectItem.PCCostItemID equals userCostingItem.CostingItemID
        select projectItem)
        .Distinct() // Distinct Records
        .ToList(); // Convert to list

【问题讨论】:

  • 链接问题不重复。问题更多的是如何进行两个右连接并选择与其中任何一个相关的记录,而不是如何进行左/右连接。
  • 首先 - LINQ 到什么? EF、SQL、对象?无论如何,如果您定义了实体之间的正确关系以及到基础表的映射,您就不必创建任何连接。使用连接而不是关系是一种强烈的气味,这表明对象模型是错误的,或者 LINQ 和 ORM 被用作普通 ADO.NET
  • Linq to objects - 感谢您提供信息,但这并不能真正回答问题。在 linq 中执行此操作的原因是因为对象来自潜在的两个不同 SQL 服务器上的数据,因此为了避免跨服务器连接,运行两个查询并使用 LINQ 选择结果。
  • 你在做什么虽然 is 是一个跨服务器连接,但它是在 第三台 机器上完成的,没有索引的好处。人们想要避免跨服务器查询的原因是链接服务器必须向主服务器发送大量数据,然后主服务器继续使用索引等进行自己的查询。但在你的情况下,two 服务器必须向应用程序发送大量数据,应用程序将在没有任何索引的情况下进行最终连接

标签: c# linq join


【解决方案1】:

这似乎给出了我需要的结果:

List<PCProjectItem> projectItems = new List<PCProjectItem>();
List<UserCostingItem> userCostingItems = new List<UserCostingItem>();
List<UserCostingItemType> userCostingItemTypes = new List<UserCostingItemType>();

projectItems = PCProjectItem.GetProjectItems(projectID, sageDatabaseID, PCIntegrationOption);
userCostingItems = UserCostingItem.GetUserCostingItems(userID, sageDatabaseID, documentType == null ? string.Empty : documentType.Value.ToString());
userCostingItemTypes = UserCostingItemType.GetUserCostingItemTypes(userID, sageDatabaseID);

//If there are no project items or allocations, return a new list now
if (projectItems.Count == 0 || (userCostingItems.Count == 0 && userCostingItemTypes.Count == 0))
{
    return new List<PCProjectItem>();
}

var results = from PCProjectItem projectItem in projectItems
              join UserCostingItem userCostingItem in userCostingItems on projectItem.PCCostItemID equals userCostingItem.CostingItemID into costingItemJoin
              from costItemRec in costingItemJoin.DefaultIfEmpty()
              join UserCostingItemType userCostingItemType in userCostingItemTypes on projectItem.PCCostItemTypeID equals userCostingItemType.CostingItemTypeID into costingItemTypeJoin
              from costItemTypeRec in costingItemTypeJoin.DefaultIfEmpty()
              where costItemTypeRec != null || costItemRec != null
              select projectItem;

return results.Distinct().ToList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-23
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    相关资源
    最近更新 更多