非常慢的实体框架执行查询

时间:2014-08-25 21:54:57

标签: c# sql-server entity-framework entity-framework-6.1

我正在使用针对SQL Server 2012的6.1.1实体框架。

我已将问题附加到此问题。

当直接针对我们的DB运行时(即从SQL Generated运行),该查询以<为15ms。

但是,在实体框架中处理时,投影的实现时间约为650毫秒(因此没有跟踪导致问题)

此外,当使用Web API和Odata进行前100时,它甚至更慢。 (例如,如果我首先在Web API控制器中对端点中的结果执行.ToArray(),则它比通过odata的过滤的前100个查询更快。

更糟糕的是,oData的inlinecount查询导致计数的groupby由Entity Framework生成,这是奇数,需要<在服务器上处理10毫秒,但实体框架处理完全选择需要相同的时间,从而使服务时间加倍。

我可以理解一些开销,但我们正在讨论投影中的100条记录,处理它的时间不应超过半秒。

另外,考虑到第二次触发的where子句(使用谓词生成)的复杂性,我会预料到,由于EF 5+中的动态缓存,它会大大加快,但它不会完全没有任何区别。

我可以为你提供它正在投影的DTO,如果它很重要但它只是字符串和datetimeoffsets直接没有任何计算或任何东西。

另请注意,所有测试均在发布模式下完成,而非调试模式。定时器用于在自定义格式化程序中隔离2个单独的查询,并计算实体框架为其提供服务所花费的时间。

我进入数据库级别并创建了一个数据库读取器并循环遍历结果并使用生成的完全相同的查询手动创建了DTO以使用(所有这些,而不是已过滤的),只需输入不同的值对于参数并且它在< 30 ms供参考。

如果您希望我以某种方式为您提供生成此内容的构建谓词,请告诉我并给我说明,我会很乐意这样做。

这是生成的查询(再次,在30毫秒内运行,但实体框架需要2.5秒才能生成结果并使用WebAPI将其发布:

SELECT TOP (@p__linq__15) 
[Project45].[Status] AS [Status], 
[Project45].[C6] AS [C1], 
[Project45].[C7] AS [C2], 
[Project45].[C1] AS [C3], 
[Project45].[C8] AS [C4], 
[Project45].[Priority] AS [Priority], 
[Project45].[C9] AS [C5], 
[Project45].[Name1] AS [Name], 
[Project45].[C10] AS [C6], 
[Project45].[Name2] AS [Name1], 
[Project45].[C11] AS [C7], 
[Project45].[C12] AS [C8], 
[Project45].[C4] AS [C9], 
[Project45].[C13] AS [C10], 
[Project45].[C5] AS [C11], 
[Project45].[C14] AS [C12], 
[Project45].[C3] AS [C13], 
[Project45].[C15] AS [C14], 
[Project45].[C2] AS [C15], 
[Project45].[C16] AS [C16], 
[Project45].[Identifier] AS [Identifier], 
[Project45].[C17] AS [C17], 
[Project45].[Name] AS [Name2], 
[Project45].[C18] AS [C18], 
[Project45].[ID] AS [ID]
FROM ( SELECT 
    [Filter1].[ID1] AS [ID], 
    [Filter1].[Identifier] AS [Identifier], 
    [Filter1].[Name1] AS [Name], 
    [Filter1].[Priority] AS [Priority], 
    [Filter1].[Status] AS [Status], 
    [Filter1].[Name2] AS [Name1], 
    [Filter1].[Name3] AS [Name2], 
     CAST( [Filter1].[DueDate] AS datetimeoffset) AS [C1], 
     CAST( CASE WHEN ([Filter1].[CancelledOn] IS NULL) THEN CASE WHEN ([Filter1].[RejectedOn1] IS NULL) THEN CASE WHEN ([Filter1].[SubmittedOn] IS NULL) THEN [Filter1].[CreatedOn] ELSE [Filter1].[SubmittedOn] END ELSE [Filter1].[RejectedOn1] END ELSE [Filter1].[CancelledOn] END AS datetimeoffset) AS [C2], 
    CASE WHEN ([Filter1].[CancelledByID] IS NOT NULL) THEN [Filter1].[UserName1] WHEN ([Filter1].[RejectedByID1] IS NOT NULL) THEN [Filter1].[UserName2] WHEN ([Filter1].[SubmittedByID] IS NOT NULL) THEN [Filter1].[UserName3] ELSE [Filter1].[UserName4] END AS [C3], 
    CASE WHEN ([Filter1].[FirstName1] IS NULL) THEN N'' ELSE [Filter1].[FirstName2] END + N' ' + CASE WHEN ([Filter1].[LastName1] IS NULL) THEN N'' ELSE [Filter1].[LastName2] END AS [C4], 
     CAST( [Filter1].[SubmittedOn] AS datetimeoffset) AS [C5], 
    N'c4eabbaf-7433-430d-bdd7-2f9180bce7cc' AS [C6], 
    N'DueDate' AS [C7], 
    N'Priority' AS [C8], 
    N'Project' AS [C9], 
    N'RequestType' AS [C10], 
    N'Status' AS [C11], 
    N'SubmittedByName' AS [C12], 
    N'SubmittedOn' AS [C13], 
    N'MajorEventBy' AS [C14], 
    N'MajorEventDate' AS [C15], 
    N'Identifier' AS [C16], 
    N'Name' AS [C17], 
    N'ID' AS [C18]
    FROM ( SELECT [Extent1].[ID] AS [ID1], [Extent1].[Identifier] AS [Identifier], [Extent1].[Name] AS [Name1], [Extent1].[Priority] AS [Priority], [Extent1].[DueDate] AS [DueDate], [Extent1].[CreatedOn] AS [CreatedOn], [Extent1].[CreatedByID] AS [CreatedByID], [Extent1].[SubmittedOn] AS [SubmittedOn], [Extent1].[SubmittedByID] AS [SubmittedByID], [Extent1].[RejectedOn] AS [RejectedOn1], [Extent1].[RejectedByID] AS [RejectedByID1], [Extent1].[CancelledOn] AS [CancelledOn], [Extent1].[CancelledByID] AS [CancelledByID], [Extent1].[Private] AS [Private], [Extent1].[Status] AS [Status], [Extent2].[UserName] AS [UserName1], [Extent3].[UserName] AS [UserName2], [Extent4].[UserName] AS [UserName3], [Extent5].[UserName] AS [UserName4], [Extent6].[Name] AS [Name2], [Extent7].[Name] AS [Name3], [Extent8].[FirstName] AS [FirstName1], [Extent9].[FirstName] AS [FirstName2], [Extent10].[LastName] AS [LastName1], [Extent11].[LastName] AS [LastName2]
        FROM           [dbo].[Requests] AS [Extent1]
        LEFT OUTER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[CancelledByID] = [Extent2].[ID]
        LEFT OUTER JOIN [dbo].[Users] AS [Extent3] ON [Extent1].[RejectedByID] = [Extent3].[ID]
        LEFT OUTER JOIN [dbo].[Users] AS [Extent4] ON [Extent1].[SubmittedByID] = [Extent4].[ID]
        INNER JOIN [dbo].[Users] AS [Extent5] ON [Extent1].[CreatedByID] = [Extent5].[ID]
        INNER JOIN [dbo].[Projects] AS [Extent6] ON [Extent1].[ProjectID] = [Extent6].[ID]
        INNER JOIN [dbo].[RequestTypes] AS [Extent7] ON [Extent1].[RequestTypeID] = [Extent7].[ID]
        LEFT OUTER JOIN [dbo].[Users] AS [Extent8] ON [Extent1].[SubmittedByID] = [Extent8].[ID]
        LEFT OUTER JOIN [dbo].[Users] AS [Extent9] ON [Extent1].[SubmittedByID] = [Extent9].[ID]
        LEFT OUTER JOIN [dbo].[Users] AS [Extent10] ON [Extent1].[SubmittedByID] = [Extent10].[ID]
        LEFT OUTER JOIN [dbo].[Users] AS [Extent11] ON [Extent1].[SubmittedByID] = [Extent11].[ID]
        WHERE [Extent1].[isDeleted] <> cast(1 as bit)
    )  AS [Filter1]
    WHERE (( EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclDataMarts] AS [Extent12]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent13]
            WHERE ([Extent12].[SecurityGroupID] = [Extent13].[SecurityGroupID]) AND ([Extent13].[UserID] = @p__linq__0)
        )) AND ([Extent12].[PermissionID] IN (cast('5d6dd388-7842-40a1-a27a-b9782a445e20' as uniqueidentifier), cast('a58791b5-e8af-48d0-b9cd-ed0b54e564e6' as uniqueidentifier), cast('0cabf382-93d3-4dac-aa80-2de500a5f945' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[RequestDataMarts] AS [Extent14]
            WHERE ([Extent12].[DataMartID] = [Extent14].[DataMartID]) AND ([Extent14].[RequestID] = [Filter1].[ID1])
        ))
    )) OR ( EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclProjects] AS [Extent15]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent16]
            WHERE ([Extent15].[SecurityGroupID] = [Extent16].[SecurityGroupID]) AND ([Extent16].[UserID] = @p__linq__1)
        )) AND ([Extent15].[PermissionID] IN (cast('5d6dd388-7842-40a1-a27a-b9782a445e20' as uniqueidentifier), cast('a58791b5-e8af-48d0-b9cd-ed0b54e564e6' as uniqueidentifier), cast('0cabf382-93d3-4dac-aa80-2de500a5f945' as uniqueidentifier), cast('0549f5c8-6c0e-4491-be90-ee0f29652422' as uniqueidentifier), cast('40db7de2-eefa-4d31-b400-7e72ab34de99' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Requests] AS [Extent17]
            WHERE ([Extent15].[ProjectID] = [Extent17].[ProjectID]) AND ([Extent17].[ID] = [Filter1].[ID1])
        ))
    )) OR ( EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclProjectDataMarts] AS [Extent18]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent19]
            WHERE ([Extent18].[SecurityGroupID] = [Extent19].[SecurityGroupID]) AND ([Extent19].[UserID] = @p__linq__2)
        )) AND ([Extent18].[PermissionID] IN (cast('5d6dd388-7842-40a1-a27a-b9782a445e20' as uniqueidentifier), cast('a58791b5-e8af-48d0-b9cd-ed0b54e564e6' as uniqueidentifier), cast('0cabf382-93d3-4dac-aa80-2de500a5f945' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[RequestDataMarts] AS [Extent20]
            WHERE ([Extent18].[DataMartID] = [Extent20].[DataMartID]) AND ([Extent20].[RequestID] = [Filter1].[ID1])
        )) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Requests] AS [Extent21]
            WHERE ([Extent18].[ProjectID] = [Extent21].[ProjectID]) AND ([Extent21].[ID] = [Filter1].[ID1])
        ))
    )) OR ( EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclGlobal] AS [Extent22]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent23]
            WHERE ([Extent22].[SecurityGroupID] = [Extent23].[SecurityGroupID]) AND ([Extent23].[UserID] = @p__linq__3)
        )) AND ([Extent22].[PermissionID] IN (cast('5d6dd388-7842-40a1-a27a-b9782a445e20' as uniqueidentifier), cast('a58791b5-e8af-48d0-b9cd-ed0b54e564e6' as uniqueidentifier), cast('0cabf382-93d3-4dac-aa80-2de500a5f945' as uniqueidentifier), cast('5ccb0ec2-006d-4345-895e-5dd2c6c8c791' as uniqueidentifier), cast('0549f5c8-6c0e-4491-be90-ee0f29652422' as uniqueidentifier), cast('40db7de2-eefa-4d31-b400-7e72ab34de99' as uniqueidentifier)))
    )) OR ( EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclRequestSharedFolders] AS [Extent24]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent25]
            WHERE ([Extent24].[SecurityGroupID] = [Extent25].[SecurityGroupID]) AND ([Extent25].[UserID] = @p__linq__4)
        )) AND ([Extent24].[PermissionID] IN (cast('5ccb0ec2-006d-4345-895e-5dd2c6c8c791' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[RequestSharedFolderRequests] AS [Extent26]
            WHERE ([Extent24].[RequestSharedFolderID] = [Extent26].[RequestSharedFolderID]) AND ([Extent26].[RequestID] = [Filter1].[ID1])
        ))
    )) OR ( EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclOrganizations] AS [Extent27]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent28]
            WHERE ([Extent27].[SecurityGroupID] = [Extent28].[SecurityGroupID]) AND ([Extent28].[UserID] = @p__linq__5)
        )) AND ([Extent27].[PermissionID] IN (cast('0549f5c8-6c0e-4491-be90-ee0f29652422' as uniqueidentifier), cast('40db7de2-eefa-4d31-b400-7e72ab34de99' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Requests] AS [Extent29]
            WHERE ([Extent27].[OrganizationID] = [Extent29].[OrganizationID]) AND ([Extent29].[ID] = [Filter1].[ID1])
        ))
    )) OR ( EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclProjectOrganizations] AS [Extent30]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent31]
            WHERE ([Extent30].[SecurityGroupID] = [Extent31].[SecurityGroupID]) AND ([Extent31].[UserID] = @p__linq__6)
        )) AND ([Extent30].[PermissionID] IN (cast('0549f5c8-6c0e-4491-be90-ee0f29652422' as uniqueidentifier), cast('40db7de2-eefa-4d31-b400-7e72ab34de99' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Requests] AS [Extent32]
            WHERE ([Extent30].[ProjectID] = [Extent32].[ProjectID]) AND ([Extent32].[ID] = [Filter1].[ID1])
        )) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Requests] AS [Extent33]
            WHERE ([Extent30].[OrganizationID] = [Extent33].[OrganizationID]) AND ([Extent33].[ID] = [Filter1].[ID1])
        ))
    ))) AND ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclDataMarts] AS [Extent34]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent35]
            WHERE ([Extent34].[SecurityGroupID] = [Extent35].[SecurityGroupID]) AND ([Extent35].[UserID] = @p__linq__7)
        )) AND ([Extent34].[PermissionID] IN (cast('5d6dd388-7842-40a1-a27a-b9782a445e20' as uniqueidentifier), cast('a58791b5-e8af-48d0-b9cd-ed0b54e564e6' as uniqueidentifier), cast('0cabf382-93d3-4dac-aa80-2de500a5f945' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[RequestDataMarts] AS [Extent36]
            WHERE ([Extent34].[DataMartID] = [Extent36].[DataMartID]) AND ([Extent36].[RequestID] = [Filter1].[ID1])
        )) AND ([Extent34].[Allowed] <> cast(1 as bit))
    )) AND ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclProjects] AS [Extent37]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent38]
            WHERE ([Extent37].[SecurityGroupID] = [Extent38].[SecurityGroupID]) AND ([Extent38].[UserID] = @p__linq__8)
        )) AND ([Extent37].[PermissionID] IN (cast('5d6dd388-7842-40a1-a27a-b9782a445e20' as uniqueidentifier), cast('a58791b5-e8af-48d0-b9cd-ed0b54e564e6' as uniqueidentifier), cast('0cabf382-93d3-4dac-aa80-2de500a5f945' as uniqueidentifier), cast('0549f5c8-6c0e-4491-be90-ee0f29652422' as uniqueidentifier), cast('40db7de2-eefa-4d31-b400-7e72ab34de99' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Requests] AS [Extent39]
            WHERE ([Extent37].[ProjectID] = [Extent39].[ProjectID]) AND ([Extent39].[ID] = [Filter1].[ID1])
        )) AND ([Extent37].[Allowed] <> cast(1 as bit))
    )) AND ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclProjectDataMarts] AS [Extent40]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent41]
            WHERE ([Extent40].[SecurityGroupID] = [Extent41].[SecurityGroupID]) AND ([Extent41].[UserID] = @p__linq__9)
        )) AND ([Extent40].[PermissionID] IN (cast('5d6dd388-7842-40a1-a27a-b9782a445e20' as uniqueidentifier), cast('a58791b5-e8af-48d0-b9cd-ed0b54e564e6' as uniqueidentifier), cast('0cabf382-93d3-4dac-aa80-2de500a5f945' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[RequestDataMarts] AS [Extent42]
            WHERE ([Extent40].[DataMartID] = [Extent42].[DataMartID]) AND ([Extent42].[RequestID] = [Filter1].[ID1])
        )) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Requests] AS [Extent43]
            WHERE ([Extent40].[ProjectID] = [Extent43].[ProjectID]) AND ([Extent43].[ID] = [Filter1].[ID1])
        )) AND ([Extent40].[Allowed] <> cast(1 as bit))
    )) AND ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclGlobal] AS [Extent44]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent45]
            WHERE ([Extent44].[SecurityGroupID] = [Extent45].[SecurityGroupID]) AND ([Extent45].[UserID] = @p__linq__10)
        )) AND ([Extent44].[PermissionID] IN (cast('5d6dd388-7842-40a1-a27a-b9782a445e20' as uniqueidentifier), cast('a58791b5-e8af-48d0-b9cd-ed0b54e564e6' as uniqueidentifier), cast('0cabf382-93d3-4dac-aa80-2de500a5f945' as uniqueidentifier), cast('5ccb0ec2-006d-4345-895e-5dd2c6c8c791' as uniqueidentifier), cast('0549f5c8-6c0e-4491-be90-ee0f29652422' as uniqueidentifier), cast('40db7de2-eefa-4d31-b400-7e72ab34de99' as uniqueidentifier))) AND ([Extent44].[Allowed] <> cast(1 as bit))
    )) AND ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclRequestSharedFolders] AS [Extent46]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent47]
            WHERE ([Extent46].[SecurityGroupID] = [Extent47].[SecurityGroupID]) AND ([Extent47].[UserID] = @p__linq__11)
        )) AND ([Extent46].[PermissionID] IN (cast('5ccb0ec2-006d-4345-895e-5dd2c6c8c791' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[RequestSharedFolderRequests] AS [Extent48]
            WHERE ([Extent46].[RequestSharedFolderID] = [Extent48].[RequestSharedFolderID]) AND ([Extent48].[RequestID] = [Filter1].[ID1])
        )) AND ([Extent46].[Allowed] <> cast(1 as bit))
    )) AND ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclOrganizations] AS [Extent49]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent50]
            WHERE ([Extent49].[SecurityGroupID] = [Extent50].[SecurityGroupID]) AND ([Extent50].[UserID] = @p__linq__12)
        )) AND ([Extent49].[PermissionID] IN (cast('0549f5c8-6c0e-4491-be90-ee0f29652422' as uniqueidentifier), cast('40db7de2-eefa-4d31-b400-7e72ab34de99' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Requests] AS [Extent51]
            WHERE ([Extent49].[OrganizationID] = [Extent51].[OrganizationID]) AND ([Extent51].[ID] = [Filter1].[ID1])
        )) AND ([Extent49].[Allowed] <> cast(1 as bit))
    )) AND ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AclProjectOrganizations] AS [Extent52]
        WHERE ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[SecurityGroupUsers] AS [Extent53]
            WHERE ([Extent52].[SecurityGroupID] = [Extent53].[SecurityGroupID]) AND ([Extent53].[UserID] = @p__linq__13)
        )) AND ([Extent52].[PermissionID] IN (cast('0549f5c8-6c0e-4491-be90-ee0f29652422' as uniqueidentifier), cast('40db7de2-eefa-4d31-b400-7e72ab34de99' as uniqueidentifier))) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Requests] AS [Extent54]
            WHERE ([Extent52].[ProjectID] = [Extent54].[ProjectID]) AND ([Extent54].[ID] = [Filter1].[ID1])
        )) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Requests] AS [Extent55]
            WHERE ([Extent52].[OrganizationID] = [Extent55].[OrganizationID]) AND ([Extent55].[ID] = [Filter1].[ID1])
        )) AND ([Extent52].[Allowed] <> cast(1 as bit))
    )) AND (([Filter1].[Private] <> cast(1 as bit)) OR (([Filter1].[Private] = 1) AND ([Filter1].[CreatedByID] = @p__linq__14)))
)  AS [Project45]
ORDER BY [Project45].[Identifier] DESC, [Project45].[ID] ASC

1 个答案:

答案 0 :(得分:1)

EF需要很长时间才能将LINQ转换为SQL查询。

您的查询未自动缓存,因为它使用内存中的集合作为参数(uuid集合)。

请参阅MSDN页面Performance Considerations (Entity Framework)

解决方案(不是很理想)是序列化此参数并使用String.Contains运算符。