如何为 nHibernate 正确翻译 LINQ string.Contains("substring%")?
How to translate LINQ string.Contains("substring%") correctly for nHibernate?
以下代码用于为 nHibernate 提供一种将我的 C# LINQ 代码转换为正确的 SQL 语句的方法。我想要的是有 3 个 SQL-语句,例如:
"Select * From HITable Where Series LIKE %substring"
或
"Select * From HITable Where Series LIKE substring%"
或
"Select * From HITable Where Series LIKE sub%ng"
问题是,当 nHibernate 得到它时,它将所有 3 种情况下的 StartsWith、EndsWith 和 Contains 转换为 %substring%,即通配符同时放在子字符串的开头和结尾。解决这个问题的正确方法是什么?
private static Expression<Func<HIProduct, bool>> CheckWildCardPosition(string rangeFrom)
{
if (rangeFrom.StartsWith(SqlWildCardAnyValue.ToString()))
{
return hip => hip.ProductId.Series.StartsWith(rangeFrom);
}
else if (rangeFrom.EndsWith(SqlWildCardAnyValue.ToString()))
{
return hip => hip.ProductId.Series.EndsWith(rangeFrom);
}
else
{
return hip => hip.ProductId.Series.Contains(rangeFrom);
}
}
我发现使用 StartsWith/EndsWith 时的问题是您必须删除 '%' 字符,否则您实际上会得到 2 个 '%' 字符。这是因为 nHibernate 将 StartsWith/EndsWith 转换为 '%'。因此,代码解决方案的初稿如下所示:
private static Expression<Func<HIProduct, bool>> CheckWildCardPosition(string serie)
{
char[] wildCard = new char[] { SqlWildCardAnyValue };
if (serie.StartsWith(SqlWildCardAnyValue.ToString()))
{
if (serie.EndsWith(SqlWildCardAnyValue.ToString()))
{
return hip => hip.ProductId.Series.Contains(serie.Trim(wildCard));
}
return hip => hip.ProductId.Series.EndsWith(serie.TrimStart(wildCard));
}
else if (serie.EndsWith(SqlWildCardAnyValue.ToString()))
{
return hip => hip.ProductId.Series.StartsWith(serie.TrimEnd(wildCard));
}
else
{
string[] split = serie.Split(wildCard);
return hip => hip.ProductId.Series.StartsWith(split[0]) && hip.ProductId.Series.EndsWith(split[1]);
}
}
请记住,这是初稿,我知道代码可以重构为更有效的代码,但第一步这解决了我的问题。
以下代码用于为 nHibernate 提供一种将我的 C# LINQ 代码转换为正确的 SQL 语句的方法。我想要的是有 3 个 SQL-语句,例如:
"Select * From HITable Where Series LIKE %substring"
或
"Select * From HITable Where Series LIKE substring%"
或
"Select * From HITable Where Series LIKE sub%ng"
问题是,当 nHibernate 得到它时,它将所有 3 种情况下的 StartsWith、EndsWith 和 Contains 转换为 %substring%,即通配符同时放在子字符串的开头和结尾。解决这个问题的正确方法是什么?
private static Expression<Func<HIProduct, bool>> CheckWildCardPosition(string rangeFrom)
{
if (rangeFrom.StartsWith(SqlWildCardAnyValue.ToString()))
{
return hip => hip.ProductId.Series.StartsWith(rangeFrom);
}
else if (rangeFrom.EndsWith(SqlWildCardAnyValue.ToString()))
{
return hip => hip.ProductId.Series.EndsWith(rangeFrom);
}
else
{
return hip => hip.ProductId.Series.Contains(rangeFrom);
}
}
我发现使用 StartsWith/EndsWith 时的问题是您必须删除 '%' 字符,否则您实际上会得到 2 个 '%' 字符。这是因为 nHibernate 将 StartsWith/EndsWith 转换为 '%'。因此,代码解决方案的初稿如下所示:
private static Expression<Func<HIProduct, bool>> CheckWildCardPosition(string serie)
{
char[] wildCard = new char[] { SqlWildCardAnyValue };
if (serie.StartsWith(SqlWildCardAnyValue.ToString()))
{
if (serie.EndsWith(SqlWildCardAnyValue.ToString()))
{
return hip => hip.ProductId.Series.Contains(serie.Trim(wildCard));
}
return hip => hip.ProductId.Series.EndsWith(serie.TrimStart(wildCard));
}
else if (serie.EndsWith(SqlWildCardAnyValue.ToString()))
{
return hip => hip.ProductId.Series.StartsWith(serie.TrimEnd(wildCard));
}
else
{
string[] split = serie.Split(wildCard);
return hip => hip.ProductId.Series.StartsWith(split[0]) && hip.ProductId.Series.EndsWith(split[1]);
}
}
请记住,这是初稿,我知道代码可以重构为更有效的代码,但第一步这解决了我的问题。