gpt4 book ai didi

c# - 组合多个 Where's 时如何格式化 linq 以用 OR 替换 AND

转载 作者:行者123 更新时间:2023-11-30 16:37:54 25 4
gpt4 key购买 nike

我有一个 Asp.net MVC C# 应用程序,其中包含一个带有以下字段的搜索页面: Search.cshtml

输入值只能包含部分,例如。 Carnet Number 可以是“Wakka 12”,并且在数据库中有一个必须返回的“Wakka 1234”记录。在 SQL 中,它将是 Where [CarnetNumber] like '%Wakka 123%'

此外,字段必须用于典型的 OR 组合,例如。如果用户在 Carnet Number 字段中输入一个值并在 Holder 字段中输入一个值,则结果应该是所有包含 Carnet Number 的记录,其中包含输入的 Carnet Number 或 Holder 字段包含 Holder 输入值的记录 - SQL 其中 [CarnetNumber] 喜欢 '%Wakka 123%' 或 [Holder] 喜欢 '%some holder%'

没有提供值的字段不应添加到查询中。

我的困难是让 OR 部分在 linq 中工作。我查看了动态 linq 和表达式,但无法使其正常工作。

这是迄今为止我最接近的解决方案:

        var Q = (from Cx in db.Carnets
where Cx.CarnetNumber.Contains(carnet.CarnetNumber)
|| Cx.Holder.Contains(carnet.Holder)
|| Cx.ImportSerial.Contains(carnet.ImportSerial)
|| Cx.CPDRegistrationNumber.Contains(carnet.CPDRegistrationNumber)
|| Cx.CPDChassis.Contains(carnet.CPDChassis)
|| Cx.CPDEngine.Contains(carnet.CPDEngine)
|| Cx.CPDMake.Contains(carnet.CPDMake)
select Cx);

这给了我一个 SQL 查询:

SELECT 
[Extent1].[CarnetNumber] AS [CarnetNumber],
[Extent1].[CarnetType] AS [CarnetType],
[Extent1].[Holder] AS [Holder],
[Extent1].[ValidUntillDate] AS [ValidUntillDate],
[Extent1].[IssuingAuthority] AS [IssuingAuthority],
[Extent1].[Currency] AS [Currency],
[Extent1].[Value] AS [Value],
[Extent1].[PortOfImport] AS [PortOfImport],
[Extent1].[ImportSerial] AS [ImportSerial],
[Extent1].[ImportDate] AS [ImportDate],
[Extent1].[PortOfExport] AS [PortOfExport],
[Extent1].[ExportSerial] AS [ExportSerial],
[Extent1].[DateOfExport] AS [DateOfExport],
[Extent1].[CarnetItems] AS [CarnetItems],
[Extent1].[CPDRegistrationNumber] AS [CPDRegistrationNumber],
[Extent1].[CPDChassis] AS [CPDChassis],
[Extent1].[CPDEngine] AS [CPDEngine],
[Extent1].[CPDMake] AS [CPDMake],
[Extent1].[CPDTransportType] AS [CPDTransportType],
[Extent1].[AcquittalStatus] AS [AcquittalStatus],
[Extent1].[LastDateProcessed] AS [LastDateProcessed],
[Extent1].[LastAccessedByUser] AS [LastAccessedByUser]
FROM [dbo].[Carnet] AS [Extent1]
WHERE ([Extent1].[CarnetNumber] LIKE @p__linq__0 ESCAPE N'~')
OR ([Extent1].[Holder] LIKE @p__linq__1 ESCAPE N'~')
OR ([Extent1].[ImportSerial] LIKE @p__linq__2 ESCAPE N'~')
OR ([Extent1].[CPDRegistrationNumber] LIKE @p__linq__3 ESCAPE N'~')
OR ([Extent1].[CPDChassis] LIKE @p__linq__4 ESCAPE N'~')
OR ([Extent1].[CPDEngine] LIKE @p__linq__5 ESCAPE N'~')
OR ([Extent1].[CPDMake] LIKE @p__linq__6 ESCAPE N'~')

现在,如果我在 SQL 中运行它并替换值 (@p_linq_#),我将一无所获,因为未提供的其他字段为 NULL。 SQL 正在执行 LIKE null 测试。

我尝试将 .Where 子句分开,但 OR 变成了 AND:

字符串搜索 = "";

var Q = db.Carnets
.Where(a => a.CarnetNumber != null);

if (carnet.CarnetNumber != null)
{
search = carnet.CarnetNumber.Trim();
Q = Q.Where(a => a.CarnetNumber.Contains(search));
}

if (carnet.Holder != null)
{
search = carnet.Holder.Trim();
Q = Q.Where(a => a.Holder.Contains(search));
}

这给出了 SQL Where :

FROM [dbo].[Carnet] AS [Extent1]
WHERE ([Extent1].[CarnetNumber] LIKE @p__linq__0 ESCAPE N'~')
AND ([Extent1].[Holder] LIKE @p__linq__1 ESCAPE N'~')

如果我在 C# 中添加 .TRIM() ,SQL Where 会变得疯狂并将其转换为 CHARINDEX 查询,因此搜索变量。

我认为第一次尝试离家更近了,但我如何从我的 linq 中删除 Where 部分中包含 Null 字段的所有字段?

最佳答案

所以您的问题正如您已经提到的那样,您正在对空值执行检查。

在您的情况下,您应该在比较之前检查您要比较的这些值是否不为空或只是一个空格

这对你来说应该是一次尝试

    var Q = (from Cx in db.Carnets
where
(!string.IsNullOrWhitespace(carnet.CarnetNumber) && Cx.CarnetNumber.Contains(carnet.CarnetNumber))
|| (!string.IsNullOrWhitespace(carnet.Holder) && Cx.Holder.Contains(carnet.Holder))
|| (!string.IsNullOrWhitespace(carnet.ImportSerial) && Cx.ImportSerial.Contains(carnet.ImportSerial))
|| (!string.IsNullOrWhitespace(carnet.CPDRegistrationNumber) && Cx.CPDRegistrationNumber.Contains(carnet.CPDRegistrationNumber))
|| (!string.IsNullOrWhitespace(carnet.CPDChassis) && Cx.CPDChassis.Contains(carnet.CPDChassis))
|| (!string.IsNullOrWhitespace(carnet.CPDEngine) && Cx.CPDEngine.Contains(carnet.CPDEngine))
|| (!string.IsNullOrWhitespace(carnet.CPDMake) && Cx.CPDMake.Contains(carnet.CPDMake))
select Cx);

如果 Linq 无法翻译 string.IsNullOrWhitespace() 函数,您必须在实际查询之外进行检查。所以你基本上建立了你的 sql 查询依赖于几个 if,最后你执行那个查询。

试试这个

var Q = from Cx in db.Carnets select Cx;

if (!string.IsNullOrWhitespace(carnet.CarnetNumber))
{
var withCarnetNumber = from Cx in Q
where Cx.CarnetNumber.Contains(carnet.CarnetNumber)
select Cx;
}

if (!string.IsNullOrWhitespace(carnet.Holder))
{
var withCarnetHolder = from Cx in Q
where Cx.CarnetHolder.Contains(carnet.Holder)
select Cx;
}

...

var result = withCarnetNumber.Union(withCarnetHolder).Union(...).ToList();

关于c# - 组合多个 Where's 时如何格式化 linq 以用 OR 替换 AND,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56670515/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com