【问题标题】:linq nested select in Contains method包含方法中的linq嵌套选择
【发布时间】:2014-06-16 23:03:20
【问题描述】:

这可以转换为单个 LINQ 语句吗?

SELECT COUNT(*) 
FROM Abstract_Dedications_Lookup 
WHERE PlatEntryNumber = 10383772 
AND CommonArea = 0 
AND ((OuterType <> '' AND OuterValue <> '') OR (InnerType <> '' AND InnerValue <> '')) 
AND ParcelNumber IN 
(SELECT ParentParcelNumber 
FROM Parcel_Title_History 
WHERE EntryNumber <> 10383772 
AND ParentParcelNumber <> '0' 
AND ChildParcelNumber <> ParentParcelNumber) 

我尝试了很多变体,但无法在“.Contains”方法中获得正确的语法。可以在“包含”中使用“选择”吗?

var query2 = from d in context.RTV_ParcelDedicationLocations
from p in context.RTV_ParcelTitleHistory
where d.PlatEntryNumber == PlatEntryNum
where d.CommonArea == false
where (d.OuterType != "" && d.OuterValue != "") || (d.InnerType != "" && d.InnerValue != "")
where d.ParcelNumber.Contains(p.ChildParcelNumber != p.ParentParcelNumber)
select d;                      
var results2 = query2.ToList();

【问题讨论】:

    标签: c# sql linq select nested


    【解决方案1】:

    您可以创建单独的 linq 语句,这些语句将由数据库作为 1 个查询执行。一个 linq 语句实际上会被执行,直到您开始对其进行迭代。

    我考虑这个问题的方法是定义一个从 Parcel_Title_History 获取有效 ParentParcelNumber 的查询。然后创建另一个查询来检查 Abstract_Deications_Lookup 中的项目是否在第一个查询中。试试这样的:

    var query1 =  from p in context.RTV_ParcelTitleHistory
                    where p.EntryNumber != 10383772 & p.ParentParcelNumber != "0" & p.ChildParcelNumber != p.ParentParcelNumber
                    select p.ParentParcelNumber;
    
    var query2 = from d in context.RTV_ParcelDedicationLocations
                    where d.PlatEntryNumber == 10383772
                    & d.CommonArea == 0
                    & ((d.OuterType != "" && d.OuterValue != "") || (d.InnerType != "" && d.InnerValue != ""))
                    & query1.Contains(d.ParcelNumber)
                    select d;
    
    var results2 = query2.ToList();
    

    【讨论】:

    • 逻辑是正确的,它运行,让我走上正轨。我有一个 out_of_memory 异常,可能是因为 ParcelTitleHistory 查询的结果计数有大约 300,000 条记录,并且该大型结果集上的 Contains 占用了大量内存。
    • query1 实际上不会返回 300,000 行,它会像在您的 OP 中一样创建 WHERE IN (SELECT...) 类型的查询。您从 query2.Count() 得到的计数是多少?编辑:实际上我假设您使用的是实体框架,如果不是这样,那么是的,query1 返回 300,000 行。
    • query2 的计数为 43,909。确实,上面的代码不会返回计数。我添加它是为了了解从 query1 返回的记录数量,然后将其删除。与 OP 的 SQL 相比,query2 的计数应该是 185。是的,我使用的是 EF。
    • 我忘了提到“out_of_memory”异常是由我在之前的查询尝试中意外添加的额外“from”子句引起的。我删除了它,没有更多的内存异常,但来自 query2 的计数仍然不正确。
    • 嗯,这很离谱。你能写出 query2.ToTraceString() 并与 OP 中的查询进行比较吗?
    【解决方案2】:

    下面的 LINQ 生成的 SQL 语句返回 44,092 条记录,但应该与返回 182 条记录的 OP 中的 SQL 相同。 query2 LINQ 中的某些内容显然不正确:

    SELECT 
    [Extent1].[ParcelNumber] AS [ParcelNumber], 
    [Extent1].[PlatEntryNumber] AS [PlatEntryNumber], 
    [Extent1].[OuterType] AS [OuterType], 
    [Extent1].[OuterValue] AS [OuterValue], 
    [Extent1].[InnerType] AS [InnerType], 
    [Extent1].[InnerValue] AS [InnerValue], 
    [Extent1].[CommonArea] AS [CommonArea]
    FROM (SELECT 
    [RTV_ParcelDedicationLocations].[ParcelNumber] AS [ParcelNumber], 
    [RTV_ParcelDedicationLocations].[PlatEntryNumber] AS [PlatEntryNumber], 
    [RTV_ParcelDedicationLocations].[OuterType] AS [OuterType], 
    [RTV_ParcelDedicationLocations].[OuterValue] AS [OuterValue], 
    [RTV_ParcelDedicationLocations].[InnerType] AS [InnerType], 
    [RTV_ParcelDedicationLocations].[InnerValue] AS [InnerValue], 
    [RTV_ParcelDedicationLocations].[CommonArea] AS [CommonArea]
    FROM [dbo].[RTV_ParcelDedicationLocations] AS [RTV_ParcelDedicationLocations]) AS [Extent1]
    WHERE (([Extent1].[PlatEntryNumber] = 10383772) AND (10383772 IS NOT NULL) 
    AND (0 = [Extent1].[CommonArea]) AND ('''' <> [Extent1].[OuterType]) AND ('''' <> [Extent1].[OuterValue])) 
    OR (('''' <> [Extent1].[InnerType]) AND ('''' <> [Extent1].[InnerValue])
    AND ( EXISTS (SELECT 1 AS [C1]
    FROM (SELECT  [RTV_ParcelTitleHistory].[EntryNumber] AS [EntryNumber], 
    [RTV_ParcelTitleHistory].[ParentParcelNumber] AS [ParentParcelNumber], 
    [RTV_ParcelTitleHistory].[ChildParcelNumber] AS [ChildParcelNumber], 
    [RTV_ParcelTitleHistory].[Book] AS [Book], 
    [RTV_ParcelTitleHistory].[Page] AS [Page]
    FROM [dbo].[RTV_ParcelTitleHistory] AS [RTV_ParcelTitleHistory]) AS [Extent2]
    WHERE ( NOT (([Extent2].[EntryNumber] = 10383772) AND (10383772 IS NOT NULL))) AND ('0' <> [Extent2].[ParentParcelNumber]) AND ([Extent2].[ChildParcelNumber] <> [Extent2].[ParentParcelNumber]) AND ([Extent2].[ParentParcelNumber] = [Extent1].[ParcelNumber])
    )))
    

    【讨论】:

      猜你喜欢
      • 2016-01-14
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      • 2018-08-10
      • 1970-01-01
      • 1970-01-01
      • 2017-08-31
      • 1970-01-01
      相关资源
      最近更新 更多