假设我有一个表Table1,其字符串字段为[ProductString],其值为: Alpha,字母数字或数字:例如ABC,B4,U2,C 5,100,U1,U5,U6,U11
我希望能够获取类似“ProductString> = U5”的where子句,并将其作为字符串传递给LINQ语句,以便进行评估
Table1.Where(t=> t.ProductString >= 'U5');
通常这会返回结果U5和U6。
但是,我希望能够以某种方式使用NaturalSortComparer,以便返回的结果是U5,U6和U11。
我知道如何在OrderBy中使用比较器,因为我希望能够在Where阶段使用它。
答案 0 :(得分:1)
使用自然排序比较器:
var comparer = new NaturalComparer();
Table1.Where(t=>
comparer.Compare(t.ProductString, "U5") >= 0);
假设您的所有产品字符串格式为U%number%,那么为什么不滥用这一事实呢?
Table1.Where(t=> int.Parse(t.ProductString.Replace("U","")) >= 5);
如果你正在使用LINQ to Entities我不确定这会编译成一个商店表达式(即SQL知道如何处理它 - 我想应该这样做。)
答案 1 :(得分:1)
考虑到已接受的答案,我对这个问题是否与LINQ to Entities有关而感到有些困惑。接受的答案似乎不是一个可以在LINQ to Entities上下文中使用的解决方案,但OP对问题的评论似乎证实这是在数据库上下文中执行的。无论如何,这个答案专门针对LINQ to Entities。
我认为在SQL Server中这样做很难,但并非不可能。问题是.NET知道NaturalSortComparer
是什么,但SQL Server(你最终想要查询的地方)没有这样的概念。我能想到的最好的想法包括两部分:
CREATE FUNCTION Naturalize(@val as nvarchar(max)) RETURNS nvarchar(1000)
。有一个非常酷的答案here,它围绕CLR函数创建一个UDF包装器来实现这一点。接下来为您的DbContext
创建一个函数映射,将上面的UDF映射到可以在DbContext
的EF查询中调用的函数。像这样:
[DbFunction("MyContext", "Naturalize")]
public static string Naturalize(this string value)
{
throw new NotSupportedException("This function can only be invoked from LINQ to Entities.");
}
一旦你掌握了这两个部分,你就可以在实体查询中使用这个新函数,在比较中使用Naturalized
值来比较字符串:
Table1.Where(t=> t.ProductString.Naturalize() >= "U5".Naturalize());
请记住,UDF将针对查询中包含的每一行执行,即上例中的整个表。在将该函数作为子查询应用之前,您需要确保将查询削减为可管理的内容。或者您可能想尝试在相关表上应用某种类型的基于UDF的索引。
答案 2 :(得分:0)
如果您要进行这样的搜索,那么最好的办法是在表格中添加两个新字段,[ProductCode]& [ProductNumber]分隔[ProductString]的两个部分。
然后你比较变成:
Table1.Where(t=> t.ProductCode == "U" && t.ProductNumer > 5);